Skip to content

Commit 1046735

Browse files
authored
bump version to 1.0.2
2 parents 8e0458b + e86ae3f commit 1046735

File tree

8 files changed

+142
-30
lines changed

8 files changed

+142
-30
lines changed
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
#!/usr/bin/awk -f
2+
3+
function add_to_group(key, value) {
4+
groups[key] = groups[key] "- " value "\n"
5+
}
6+
7+
{
8+
if (NF > 0) { # Skip empty lines
9+
if (tolower($1) == "feat:") {
10+
add_to_group("Features:", substr($0, index($0, $2)))
11+
} else if (tolower($1) == "fix:") {
12+
add_to_group("Fixes:", substr($0, index($0, $2)))
13+
} else {
14+
next
15+
}
16+
}
17+
}
18+
19+
END {
20+
for (group in groups) {
21+
print "\n### " group
22+
print groups[group]
23+
}
24+
print "\n"
25+
}

.github/workflows/kick-off-release.yaml

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ jobs:
4343
- name: Checkout Code
4444
uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
4545
with:
46-
ref: main
46+
fetch-depth: 0
4747

4848
- name: Bump versions to ${{ env.RELEASE_VERSION }}
4949
run: |
@@ -56,6 +56,34 @@ jobs:
5656
git push origin HEAD
5757
shell: bash
5858

59+
- name: Generate CHANGELOG
60+
env:
61+
RELEASE_VERSION: ${{ github.event.inputs.release-version }}
62+
shell: bash
63+
run: |
64+
LOGS=$(git log --pretty=format:%s origin/release..HEAD | awk -F '\n' '{print $1}')
65+
GROUPED_LOGS=$(echo $LOGS | ./.github/scripts/group-commit-message.awk)
66+
awk -v date=$(date +"%Y-%m-%d") \
67+
-v version="$RELEASE_VERSION" '
68+
NR == 2 {
69+
print "\n"
70+
print "## " version " - (" date ")"
71+
while (getline line < "/dev/stdin") {
72+
print line
73+
}
74+
next
75+
}
76+
{print}
77+
' CHANGELOG.md < <(echo "$GROUPED_LOGS") > temp && mv temp CHANGELOG.md
78+
79+
- name: Create CHANGELOG commit
80+
env:
81+
RELEASE_VERSION: ${{ github.event.inputs.release-version }}
82+
run: |
83+
git add CHANGELOG.md
84+
git commit -m "chore: update CHANGELOG for $RELEASE_VERSION"
85+
git push origin HEAD
86+
5987
- name: Create Pull Request
6088
env:
6189
GH_TOKEN: ${{ github.token }}

CHANGELOG.md

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,23 @@
11
# Changelog
22

3-
## 1.0.0 - (2024-08-26)
3+
4+
## 1.0.2 - (2025-06-10)
5+
6+
## 1.0.1 (2024-09-27)
7+
8+
## Fixes
9+
10+
- inject auth info to appsync handshake headers ([#22](https://github.com/aws-amplify/aws-appsync-apollo-extensions-swift/pull/22))
11+
12+
## 1.0.0 (2024-09-10)
413

514
### Features
15+
616
- Add heart beat monitor to AppSyncRTC. ([#1](https://github.com/aws-amplify/aws-appsync-apollo-extensions-swift/pull/1))
717
- Add user-agent header to GraphQL requests. ([#2](https://github.com/aws-amplify/aws-appsync-apollo-extensions-swift/pull/2))
818
- Initial implementation and tests.
919

1020
### Fixes
21+
1122
- Rename to Extensions. ([#3](https://github.com/aws-amplify/aws-appsync-apollo-extensions-swift/pull/3))
1223
- Add more info to user-agent header. ([#5](https://github.com/aws-amplify/aws-appsync-apollo-extensions-swift/pull/5))

Sources/AWSAppSyncApolloExtensions/Utilities/PackageInfo.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ import AppKit
2121

2222
class PackageInfo {
2323

24-
private static let version = "1.0.1"
24+
private static let version = "1.0.2"
2525

2626
@MainActor
2727
private static var os: (name: String, version: String) = {

Sources/AWSAppSyncApolloExtensions/Websocket/AppSyncWebSocketClient.swift

Lines changed: 29 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -79,36 +79,46 @@ public class AppSyncWebSocketClient: NSObject, ApolloWebSocket.WebSocketClient,
7979
}
8080

8181
public func connect() {
82-
AppSyncApolloLogger.debug("Calling Connect")
83-
guard connection?.state != .running else {
84-
AppSyncApolloLogger.debug("[AppSyncWebSocketClient] WebSocket is already in connecting state")
85-
return
86-
}
87-
88-
subscribeToAppSyncResponse()
89-
90-
Task {
82+
taskQueue.async { [weak self] in
83+
guard let self else { return }
84+
AppSyncApolloLogger.debug("Calling Connect")
85+
guard connection?.state != .running else {
86+
AppSyncApolloLogger.debug("[AppSyncWebSocketClient] WebSocket is already in connecting state")
87+
return
88+
}
89+
90+
subscribeToAppSyncResponse()
91+
9192
AppSyncApolloLogger.debug("[AppSyncWebSocketClient] Creating new connection and starting read")
92-
self.connection = try await createWebSocketConnection()
93+
self.connection = try await self.createWebSocketConnection()
94+
9395
// Perform reading from a WebSocket in a separate task recursively to avoid blocking the execution.
94-
Task { await self.startReadMessage() }
96+
Task {
97+
await self.startReadMessage()
98+
}
99+
95100
self.connection?.resume()
96101
}
97102
}
98103

99104
public func disconnect(forceTimeout: TimeInterval?) {
100-
AppSyncApolloLogger.debug("Calling Disconnect")
101-
heartBeatMonitorCancellable?.cancel()
102-
guard connection?.state == .running else {
103-
AppSyncApolloLogger.debug("[AppSyncWebSocketClient] client should be in connected state to trigger disconnect")
104-
return
105+
taskQueue.async { [weak self] in
106+
guard let self else { return }
107+
AppSyncApolloLogger.debug("Calling Disconnect")
108+
heartBeatMonitorCancellable?.cancel()
109+
guard connection?.state == .running else {
110+
AppSyncApolloLogger.debug("[AppSyncWebSocketClient] client should be in connected state to trigger disconnect")
111+
return
112+
}
113+
114+
connection?.cancel(with: .goingAway, reason: nil)
105115
}
106-
107-
connection?.cancel(with: .goingAway, reason: nil)
108116
}
109117

110118
public func write(ping: Data, completion: (() -> Void)?) {
111-
AppSyncApolloLogger.debug("Not called, not implemented.")
119+
taskQueue.async {
120+
AppSyncApolloLogger.debug("Not called, not implemented.")
121+
}
112122
}
113123

114124
public func write(string: String) {

Tests/AWSAppSyncApolloExtensionsTests/Websocket/AppSyncWebSocketClientTests.swift

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,31 @@ final class AppSyncWebSocketClientTests: XCTestCase {
3939
let webSocketClient = AppSyncWebSocketClient(endpointURL: endpoint, authorizer: MockAppSyncAuthorizer())
4040
await verifyConnected(webSocketClient)
4141
}
42+
43+
func testConnect_ConcurrentInvoke() async throws {
44+
guard let endpoint = try localWebSocketServer?.start() else {
45+
XCTFail("Local WebSocket server failed to start")
46+
return
47+
}
48+
let webSocketClient = AppSyncWebSocketClient(endpointURL: endpoint, authorizer: MockAppSyncAuthorizer())
49+
let connectedExpectation = expectation(description: "WebSocket should received connected event only once")
50+
connectedExpectation.expectedFulfillmentCount = 1
51+
let sink = webSocketClient.publisher.sink { event in
52+
switch event {
53+
case .connected:
54+
connectedExpectation.fulfill()
55+
default:
56+
XCTFail("No other type of event should be received")
57+
}
58+
}
59+
60+
for _ in 1...100 {
61+
let task = Task {
62+
webSocketClient.connect()
63+
}
64+
}
65+
await fulfillment(of: [connectedExpectation], timeout: 5)
66+
}
4267

4368
func testDisconnect_didDisconnectFromRemote() async throws {
4469
var cancellables = Set<AnyCancellable>()

Tests/IntegrationTestApp/IntegrationTestAppTests/APIKeyTests.swift

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,9 @@ final class APIKeyTests: IntegrationTestBase {
138138
}
139139

140140
func testMaxSubscriptionReached() async throws {
141+
let subscriptionLimit = 200
142+
let failedSubscriptionCount = 5
143+
141144
let configuration = try AWSAppSyncConfiguration(with: .amplifyOutputs)
142145
let store = ApolloStore(cache: InMemoryNormalizedCache())
143146
let authorizer = APIKeyAuthorizer(apiKey: configuration.apiKey ?? "")
@@ -148,8 +151,11 @@ final class APIKeyTests: IntegrationTestBase {
148151
let websocket = AppSyncWebSocketClient(endpointURL: configuration.endpoint,
149152
authorizer: authorizer)
150153
let receivedConnection = expectation(description: "received connection")
154+
receivedConnection.expectedFulfillmentCount = subscriptionLimit
155+
151156
let receivedMaxSubscriptionsReachedError = expectation(description: "received MaxSubscriptionsReachedError")
152-
receivedConnection.expectedFulfillmentCount = 100
157+
receivedMaxSubscriptionsReachedError.expectedFulfillmentCount = failedSubscriptionCount
158+
153159
let sink = websocket.publisher.sink { event in
154160
if case .string(let message) = event {
155161
if message.contains("start_ack") {
@@ -167,13 +173,18 @@ final class APIKeyTests: IntegrationTestBase {
167173
webSocketNetworkTransport: webSocketTransport
168174
)
169175
let client = ApolloClient(networkTransport: splitTransport, store: store)
170-
171-
for _ in 1...101 {
172-
_ = client.subscribe(subscription: OnCreateSubscription()) { _ in
173-
}
176+
177+
try await Task.sleep(nanoseconds: 5 * 1_000_000_000) // 5 seconds
178+
179+
var cancellables = [Cancellable]()
180+
for _ in 1...subscriptionLimit + failedSubscriptionCount {
181+
cancellables.append(client.subscribe(subscription: OnCreateSubscription()) { _ in })
174182
}
175-
183+
176184
await fulfillment(of: [receivedConnection, receivedMaxSubscriptionsReachedError], timeout: 10)
185+
186+
for cancellable in cancellables {
187+
cancellable.cancel()
188+
}
177189
}
178-
179190
}

Tests/IntegrationTestApp/IntegrationTestAppTests/AuthTokenTests.swift

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ final class AuthTokenTests: IntegrationTestBase {
9090
let receivedDisconnectError = expectation(description: "received disconnect")
9191
receivedDisconnectError.assertForOverFulfill = false
9292
let sink = websocket.publisher.sink { event in
93-
if case .error(let error) = event, error.localizedDescription.contains("Socket is not connected") {
93+
if case .disconnected(_, _) = event {
9494
receivedDisconnectError.fulfill()
9595
}
9696
}
@@ -99,8 +99,10 @@ final class AuthTokenTests: IntegrationTestBase {
9999
uploadingNetworkTransport: transport,
100100
webSocketNetworkTransport: webSocketTransport
101101
)
102+
102103
let apolloCUPInvalidToken = ApolloClient(networkTransport: splitTransport, store: store)
103104

105+
try await Task.sleep(nanoseconds: 5 * 1_000_000_000) // 5 seconds
104106
await fulfillment(of: [receivedDisconnectError], timeout: 10)
105107
}
106108

0 commit comments

Comments
 (0)