spetz commented on code in PR #4714:
URL: https://github.com/apache/iggy/pull/4714#discussion_r4456421875


##########
.github/actions/swift/post-merge/action.yml:
##########
@@ -0,0 +1,107 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+name: swift-post-merge
+description: Swift post-merge tag preparation github iggy actions
+
+inputs:
+  version:
+    description: "Version for tagging (without the 'v' prefix)"
+    required: true
+  tag:
+    description: "Git tag the publish workflow creates for this version"
+    required: true
+  dry_run:
+    description: "Dry run mode"
+    required: false
+    default: "false"
+
+runs:
+  using: "composite"
+  steps:
+    # Build metadata cannot distinguish versions with the same SwiftPM 
precedence.
+    - name: Validate version and tag
+      shell: bash
+      env:
+        VERSION: ${{ inputs.version }}
+        TAG: ${{ inputs.tag }}
+      run: |
+        set -euo pipefail
+        PRERELEASE='(0|[1-9][0-9]*|[0-9]*[A-Za-z-][0-9A-Za-z-]*)'
+        
SEMVER="^(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)(-${PRERELEASE}(\.${PRERELEASE})*)?$"
+        if ! [[ "$VERSION" =~ $SEMVER ]]; then
+          echo "❌ Invalid Swift SDK version: $VERSION"
+          echo "Expected X.Y.Z or X.Y.Z-prerelease, without build metadata"
+          exit 1
+        fi
+        if [ "$TAG" != "v${VERSION}" ]; then
+          echo "❌ Tag $TAG does not match version $VERSION, expected 
v${VERSION}"
+          exit 1
+        fi
+        echo "✅ Version $VERSION, tag $TAG"
+
+    # SwiftPM consumers receive the root manifest and legal files with the 
repository.
+    - name: Check package and legal files
+      shell: bash
+      run: |
+        set -euo pipefail
+        for file in Package.swift LICENSE NOTICE foreign/swift/LICENSE 
foreign/swift/NOTICE; do
+          if [ ! -f "$file" ]; then
+            echo "❌ Missing $file"
+            exit 1
+          fi
+        done
+        echo "✅ Root manifest and legal files present"
+
+    - name: Setup Swift
+      uses: ./.github/actions/utils/setup-swift
+      with:
+        cache-key: "release"
+        package-path: "."
+
+    # An unpinned release build checks dependency resolution before the tag 
exists.
+    - name: Build the published package
+      shell: bash
+      run: swift build -c release --product Iggy

Review Comment:
   Fixed. The build moved to a new `build-swift-package` job with `contents: 
read` and `persist-credentials: false` (`.github/workflows/publish.yml:670`), 
and `publish` runs only when that job succeeded or was skipped 
(`.github/workflows/publish.yml:1049`), so no row tags after a failed Swift 
build. The Swift action in the publish row now only validates the version, the 
tag and the legal files. The job reads no cache, since the point is the cold 
resolve a consumer gets.



##########
Package.swift:
##########
@@ -0,0 +1,57 @@
+// swift-tools-version: 6.0
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+// SwiftPM resolves packages only from a repository root. CI keeps this in 
sync with foreign/swift/Package.swift.
+
+import PackageDescription
+
+let package = Package(

Review Comment:
   Documented with measured numbers (`foreign/swift/README.md:55`). A `git 
clone --mirror` today transfers a 145 MiB pack with 3353 pull refs, against 111 
MiB for heads and tags alone, and then checks out the 67 MiB tree. A swift-only 
repository was weighed before this PR and rejected: it needs a cross-repository 
push credential, Infra approval for automated pushes and recovery for a release 
split across two repositories, to save a one-time clone that SwiftPM caches.



##########
Package.swift:
##########
@@ -0,0 +1,57 @@
+// swift-tools-version: 6.0
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+// SwiftPM resolves packages only from a repository root. CI keeps this in 
sync with foreign/swift/Package.swift.
+
+import PackageDescription
+
+let package = Package(
+    name: "iggy",
+    platforms: [
+        .macOS(.v13),
+        .iOS(.v16),
+        .tvOS(.v16),
+        .watchOS(.v9),
+        .visionOS(.v1),
+    ],
+    products: [
+        .library(name: "Iggy", targets: ["Iggy"])
+    ],
+    dependencies: [
+        .package(url: "https://github.com/apple/swift-nio.git";, from: 
"2.80.0"),
+        .package(url: "https://github.com/apple/swift-nio-ssl.git";, from: 
"2.29.0"),
+        .package(url: "https://github.com/apple/swift-log.git";, from: "1.6.0"),
+        .package(url: "https://github.com/apple/swift-crypto.git";, 
"3.0.0"..<"4.0.0"),

Review Comment:
   Widened to `"3.0.0"..<"6.0.0"` in both manifests (`Package.swift:39`, 
`foreign/swift/Package.swift:37`). swift-crypto 4.x and 5.x declare tools 
versions 6.1 and 6.2, so a Swift 6.0 toolchain skips them and still resolves 
3.x. A release build of the root package without a lockfile resolved 5.1.1 and 
built, and the SDK suite (485 tests) passed against 5.1.1 as well as against 
the pinned 3.15.1.



##########
.github/actions/swift/post-merge/action.yml:
##########
@@ -0,0 +1,107 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+name: swift-post-merge
+description: Swift post-merge tag preparation github iggy actions
+
+inputs:
+  version:
+    description: "Version for tagging (without the 'v' prefix)"
+    required: true
+  tag:
+    description: "Git tag the publish workflow creates for this version"
+    required: true
+  dry_run:
+    description: "Dry run mode"
+    required: false
+    default: "false"
+
+runs:
+  using: "composite"
+  steps:
+    # Build metadata cannot distinguish versions with the same SwiftPM 
precedence.
+    - name: Validate version and tag
+      shell: bash
+      env:
+        VERSION: ${{ inputs.version }}
+        TAG: ${{ inputs.tag }}
+      run: |
+        set -euo pipefail
+        PRERELEASE='(0|[1-9][0-9]*|[0-9]*[A-Za-z-][0-9A-Za-z-]*)'
+        
SEMVER="^(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)(-${PRERELEASE}(\.${PRERELEASE})*)?$"
+        if ! [[ "$VERSION" =~ $SEMVER ]]; then
+          echo "❌ Invalid Swift SDK version: $VERSION"
+          echo "Expected X.Y.Z or X.Y.Z-prerelease, without build metadata"
+          exit 1
+        fi
+        if [ "$TAG" != "v${VERSION}" ]; then
+          echo "❌ Tag $TAG does not match version $VERSION, expected 
v${VERSION}"
+          exit 1
+        fi
+        echo "✅ Version $VERSION, tag $TAG"
+
+    # SwiftPM consumers receive the root manifest and legal files with the 
repository.
+    - name: Check package and legal files
+      shell: bash
+      run: |
+        set -euo pipefail
+        for file in Package.swift LICENSE NOTICE foreign/swift/LICENSE 
foreign/swift/NOTICE; do
+          if [ ! -f "$file" ]; then
+            echo "❌ Missing $file"
+            exit 1
+          fi
+        done
+        echo "✅ Root manifest and legal files present"
+
+    - name: Setup Swift
+      uses: ./.github/actions/utils/setup-swift
+      with:
+        cache-key: "release"
+        package-path: "."
+
+    # An unpinned release build checks dependency resolution before the tag 
exists.
+    - name: Build the published package
+      shell: bash
+      run: swift build -c release --product Iggy
+
+    - name: Summary
+      shell: bash
+      env:
+        VERSION: ${{ inputs.version }}
+        TAG: ${{ inputs.tag }}
+        DRY_RUN: ${{ inputs.dry_run }}
+      run: |
+        {
+          echo "## 🏷️ Swift Package Tag"
+          echo ""
+          echo "| Property | Value |"
+          echo "|----------|-------|"
+          echo "| **Version** | \`${VERSION}\` |"
+          echo "| **Git Tag** | \`${TAG}\` |"
+          echo "| **Package URL** | \`https://github.com/${{ github.repository 
}}.git\` |"
+          echo ""
+          echo "\`\`\`swift"
+          echo ".package(url: \"https://github.com/${{ github.repository 
}}.git\", exact: \"${VERSION}\")"
+          echo ".product(name: \"Iggy\", package: \"iggy\")"
+          echo "\`\`\`"
+          echo ""
+          if [ "$DRY_RUN" = "true" ]; then
+            echo "**Note:** Dry run, no tag will be created"
+          else
+            echo "**Note:** The publish workflow creates the tag after this 
step"

Review Comment:
   Dropped the note. The summary now only says when a dry run creates no tag 
(`.github/actions/swift/post-merge/action.yml:92`).



##########
foreign/swift/README.md:
##########
@@ -36,20 +36,20 @@ The SDK depends on 
[SwiftNIO](https://github.com/apple/swift-nio),
 
 ## Installation
 
-Swift Package Manager fetches a package from the root of a git repository, so 
the SDK
-cannot be depended on straight from this monorepo's subdirectory. Add it 
through the
-package mirror, which carries every release as a `v<version>` tag:
+Swift Package Manager resolves a package from the root of a git repository, so 
the Iggy repository root carries a `Package.swift` that publishes this SDK. 
Depend on the Iggy repository itself, replacing `0.1.10` with a released 
version:
 
 ```swift
 // Package.swift
 dependencies: [
-    .package(url: "https://github.com/apache/iggy-swift.git";, from: "0.1.1")
+    .package(url: "https://github.com/apache/iggy.git";, from: "0.1.10")

Review Comment:
   Fixed. The section says there is no stable Swift release yet and shows the 
`exact:` snapshot form until there is (`foreign/swift/README.md:41`).



##########
foreign/swift/README.md:
##########
@@ -36,20 +36,20 @@ The SDK depends on 
[SwiftNIO](https://github.com/apple/swift-nio),
 
 ## Installation
 
-Swift Package Manager fetches a package from the root of a git repository, so 
the SDK
-cannot be depended on straight from this monorepo's subdirectory. Add it 
through the
-package mirror, which carries every release as a `v<version>` tag:
+Swift Package Manager resolves a package from the root of a git repository, so 
the Iggy repository root carries a `Package.swift` that publishes this SDK. 
Depend on the Iggy repository itself, replacing `0.1.10` with a released 
version:
 
 ```swift
 // Package.swift
 dependencies: [
-    .package(url: "https://github.com/apache/iggy-swift.git";, from: "0.1.1")
+    .package(url: "https://github.com/apache/iggy.git";, from: "0.1.10")

Review Comment:
   Fixed. Once a stable release exists, the README recommends 
`.upToNextMinor(from:)` and says why while the SDK is 0.x 
(`foreign/swift/README.md:53`).



##########
foreign/swift/README.md:
##########
@@ -36,20 +36,20 @@ The SDK depends on 
[SwiftNIO](https://github.com/apple/swift-nio),
 
 ## Installation
 
-Swift Package Manager fetches a package from the root of a git repository, so 
the SDK
-cannot be depended on straight from this monorepo's subdirectory. Add it 
through the
-package mirror, which carries every release as a `v<version>` tag:
+Swift Package Manager resolves a package from the root of a git repository, so 
the Iggy repository root carries a `Package.swift` that publishes this SDK. 
Depend on the Iggy repository itself, replacing `0.1.10` with a released 
version:
 
 ```swift
 // Package.swift
 dependencies: [
-    .package(url: "https://github.com/apache/iggy-swift.git";, from: "0.1.1")
+    .package(url: "https://github.com/apache/iggy.git";, from: "0.1.10")
 ],
 targets: [
-    .target(name: "MyApp", dependencies: [.product(name: "Iggy", package: 
"iggy-swift")])
+    .target(name: "MyApp", dependencies: [.product(name: "Iggy", package: 
"iggy")])
 ]
 ```
 
+Stable Swift releases use `vX.Y.Z` tags after PMC approval. An `X.Y.Z-edge.N` 
tag is a development snapshot of unreleased changes, not an Apache release. A 
version range such as `from: "0.1.10"` never selects a snapshot. The first 
resolve clones the whole Iggy repository, which SwiftPM then caches.

Review Comment:
   Added. A requirement must start at the first stable `v0.1.x` tag, because 
the `0.0.4` to `0.0.52` tags predate the Swift SDK and have no root manifest 
(`foreign/swift/README.md:53`).



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to