Skip to content

Commit

Permalink
chore: kickoff release
Browse files Browse the repository at this point in the history
  • Loading branch information
5d authored Aug 19, 2024
2 parents 99c72db + 5d54b5d commit 0dabc4f
Show file tree
Hide file tree
Showing 9 changed files with 180 additions and 73 deletions.
8 changes: 4 additions & 4 deletions .github/workflows/issue_closed.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,16 +10,16 @@ permissions:
jobs:
cleanup-labels:
runs-on: ubuntu-latest
if: ${{ (contains(github.event.issue.labels.*.name, 'pending-response') || contains(github.event.issue.labels.*.name, 'closing soon') || contains(github.event.issue.labels.*.name, 'pending-release')) }}
if: ${{ (contains(github.event.issue.labels.*.name, 'pending-community-response') || contains(github.event.issue.labels.*.name, 'pending-maintainer-response') || contains(github.event.issue.labels.*.name, 'closing soon') || contains(github.event.issue.labels.*.name, 'pending-release')|| contains(github.event.issue.labels.*.name, 'pending-triage')) }}
steps:
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 #v4.1.1
- name: remove unnecessary labels after closing
shell: bash
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
ISSUE_NUMBER: ${{ github.event.issue.number }}
REPOSITORY_NAME: ${{ github.event.repository.full_name }}
run: |
gh issue edit $ISSUE_NUMBER --remove-label "closing soon" --remove-label "pending-response" --remove-label "pending-release"
gh issue edit $ISSUE_NUMBER --repo $REPOSITORY_NAME --remove-label "closing soon" --remove-label "pending-community-response" --remove-label "pending-maintainer-response" --remove-label "pending-release" --remove-label "pending-triage"
comment-visibility-warning:
runs-on: ubuntu-latest
Expand All @@ -30,4 +30,4 @@ jobs:
message: |
This issue is now closed. Comments on closed issues are hard for our team to see.
If you need more assistance, please open a new issue that references this one.
If you wish to keep having a conversation with other community members under this issue feel free to do so.
If you wish to keep having a conversation with other community members under this issue feel free to do so.
26 changes: 18 additions & 8 deletions .github/workflows/issue_comment.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,17 +19,27 @@ jobs:
shell: bash
run: echo $COMMENT | sed "s/\\\n/. /g; s/\\\r//g; s/[^a-zA-Z0-9 &().,:]//g" | xargs -I {} curl -s POST "$WEBHOOK_URL" -H "Content-Type:application/json" --data '{"comment":"{}", "commentUrl":"'$COMMENT_URL'", "user":"'$USER'"}'

remove-pending-response-label:
adjust-labels:
runs-on: ubuntu-latest
permissions:
issues: write
if: ${{ !github.event.issue.pull_request && contains(github.event.issue.labels.*.name, 'pending-response') }}
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
ISSUE_NUMBER: ${{ github.event.issue.number }}
REPOSITORY_NAME: ${{ github.event.repository.full_name }}
steps:
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 #v4.1.1
- name: remove unnecessary labels after closing
- name: remove pending-community-response when new comment received
if: ${{ !contains(fromJSON('["MEMBER", "OWNER"]'), github.event.comment.author_association) && !github.event.issue.pull_request }}
shell: bash
run: |
gh issue edit $ISSUE_NUMBER --repo $REPOSITORY_NAME --remove-label "pending-community-response"
- name: add pending-maintainer-response when new community comment received
if: ${{ !contains(fromJSON('["MEMBER", "OWNER"]'), github.event.comment.author_association) }}
shell: bash
run: |
gh issue edit $ISSUE_NUMBER --repo $REPOSITORY_NAME --add-label "pending-maintainer-response"
- name: remove pending-maintainer-response when new owner/member comment received
if: ${{ contains(fromJSON('["MEMBER", "OWNER"]'), github.event.comment.author_association) }}
shell: bash
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
ISSUE_NUMBER: ${{ github.event.issue.number }}
run: |
gh issue edit $ISSUE_NUMBER --remove-label "pending-response"
gh issue edit $ISSUE_NUMBER --repo $REPOSITORY_NAME --remove-label "pending-maintainer-response"
23 changes: 22 additions & 1 deletion .github/workflows/issue_opened.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,26 @@ jobs:
shell: bash
run: echo $ISSUE | sed 's/[^a-zA-Z0-9 &().,:]//g' | xargs -I {} curl -s POST "$WEBHOOK_URL" -H "Content-Type:application/json" --data '{"issue":"{}", "issueUrl":"'$ISSUE_URL'", "user":"'$USER'"}'

add-issue-opened-labels:
runs-on: ubuntu-latest
permissions:
issues: write
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
ISSUE_NUMBER: ${{ github.event.issue.number }}
REPOSITORY_NAME: ${{ github.event.repository.full_name }}
steps:
- name: Add the pending-triage label
shell: bash
run: |
gh issue edit $ISSUE_NUMBER --repo $REPOSITORY_NAME --add-label "pending-triage"
- name: Add the pending-maintainer-response label
if: ${{ !contains(fromJSON('["MEMBER", "OWNER"]'), github.event.issue.author_association) }}
shell: bash
run: |
gh issue edit $ISSUE_NUMBER --repo $REPOSITORY_NAME --add-label "pending-maintainer-response"

maintainer-opened:
runs-on: ubuntu-latest
permissions:
Expand All @@ -29,5 +49,6 @@ jobs:
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
ISSUE_NUMBER: ${{ github.event.issue.number }}
REPOSITORY_NAME: ${{ github.event.repository.full_name }}
run: |
gh issue comment $ISSUE_NUMBER --repo aws-amplify/amplify-swift -b "This issue was opened by a maintainer of this repository; updates will be posted here. If you are also experiencing this issue, please comment here with any relevant information so that we're aware and can prioritize accordingly."
gh issue comment $ISSUE_NUMBER --repo $REPOSITORY_NAME -b "This issue was opened by a maintainer of this repository; updates will be posted here. If you are also experiencing this issue, please comment here with any relevant information so that we're aware and can prioritize accordingly."
Original file line number Diff line number Diff line change
Expand Up @@ -131,17 +131,17 @@ class AWSTranscribeStreamingAdapter: AWSTranscribeStreamingBehavior {
continuation.yield(transcribedPayload)
let isPartial = transcribedPayload.transcript?.results?.map(\.isPartial) ?? []
let shouldContinue = isPartial.allSatisfy { $0 }
return shouldContinue
return shouldContinue ? .continueToReceive : .stopAndInvalidateSession
} catch {
return true
return .continueToReceive
}
case .success(.string):
return true
return .continueToReceive
case .failure(let error):
continuation.finish(throwing: error)
return false
return .stopAndInvalidateSession
@unknown default:
return true
return .continueToReceive
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,14 @@ public final class FaceLivenessSession: LivenessService {
let baseURL: URL
var serverEventListeners: [LivenessEventKind.Server: (FaceLivenessSession.SessionConfiguration) -> Void] = [:]
var onComplete: (ServerDisconnection) -> Void = { _ in }
var serverDate: Date?
var savedURLForReconnect: URL?
var connectingState: ConnectingState = .normal

enum ConnectingState {
case normal
case reconnect
}

private let livenessServiceDispatchQueue = DispatchQueue(
label: "com.amazon.aws.amplify.liveness.service",
Expand All @@ -35,12 +43,16 @@ public final class FaceLivenessSession: LivenessService {
self.websocket = websocket

websocket.onMessageReceived { [weak self] result in
self?.receive(result: result) ?? false
self?.receive(result: result) ?? .stopAndInvalidateSession
}

websocket.onSocketClosed { [weak self] closeCode in
self?.onComplete(.unexpectedClosure(closeCode))
}

websocket.onServerDateReceived { [weak self] serverDate in
self?.serverDate = serverDate
}
}

public var onServiceException: (FaceLivenessSessionError) -> Void = { _ in }
Expand Down Expand Up @@ -75,6 +87,7 @@ public final class FaceLivenessSession: LivenessService {
guard let url = components?.url
else { throw FaceLivenessSessionError.invalidURL }

savedURLForReconnect = url
let signedConnectionURL = signer.sign(url: url)
websocket.open(url: signedConnectionURL)
}
Expand All @@ -93,17 +106,22 @@ public final class FaceLivenessSession: LivenessService {
]
)

let eventDate = eventDate()
let dateForSigning: Date
if let serverDate = serverDate {
dateForSigning = serverDate
} else {
dateForSigning = eventDate()
}

let signedPayload = self.signer.signWithPreviousSignature(
payload: encodedPayload,
dateHeader: (key: ":date", value: eventDate)
dateHeader: (key: ":date", value: dateForSigning)
)

let encodedEvent = self.eventStreamEncoder.encode(
payload: encodedPayload,
headers: [
":date": .timestamp(eventDate),
":date": .timestamp(dateForSigning),
":chunk-signature": .data(signedPayload)
]
)
Expand All @@ -115,7 +133,7 @@ public final class FaceLivenessSession: LivenessService {
}
}

private func fallbackDecoding(_ message: EventStream.Message) -> Bool {
private func fallbackDecoding(_ message: EventStream.Message) -> WebSocketSession.WebSocketMessageResult {
// We only care about two events above.
// Just in case the header value changes (it shouldn't)
// We'll try to decode each of these events
Expand All @@ -124,12 +142,12 @@ public final class FaceLivenessSession: LivenessService {
self.serverEventListeners[.challenge]?(sessionConfiguration)
} else if (try? JSONDecoder().decode(DisconnectEvent.self, from: message.payload)) != nil {
onComplete(.disconnectionEvent)
return false
return .stopAndInvalidateSession
}
return true
return .continueToReceive
}

private func receive(result: Result<URLSessionWebSocketTask.Message, Error>) -> Bool {
private func receive(result: Result<URLSessionWebSocketTask.Message, Error>) -> WebSocketSession.WebSocketMessageResult {
switch result {
case .success(.data(let data)):
do {
Expand All @@ -145,28 +163,41 @@ public final class FaceLivenessSession: LivenessService {
)
let sessionConfiguration = sessionConfiguration(from: payload)
serverEventListeners[.challenge]?(sessionConfiguration)
return true
return .continueToReceive
case .disconnect:
// :event-type DisconnectionEvent
onComplete(.disconnectionEvent)
return false
return .stopAndInvalidateSession
default:
return true
return .continueToReceive
}
} else if let exceptionType = message.headers.first(where: { $0.name == ":exception-type" }) {
let exceptionEvent = LivenessEventKind.Exception(rawValue: exceptionType.value)
onServiceException(.init(event: exceptionEvent))
return false
Amplify.log.verbose("\(#function): Received exception: \(exceptionEvent)")
guard exceptionEvent == .invalidSignature,
connectingState == .normal,
let savedURLForReconnect = savedURLForReconnect,
let serverDate = serverDate else {
onServiceException(.init(event: exceptionEvent))
return .stopAndInvalidateSession
}

connectingState = .reconnect
let signedConnectionURL = signer.sign(
url: savedURLForReconnect,
date: { serverDate }
)
return .invalidateSessionAndRetry(url: signedConnectionURL)
} else {
return fallbackDecoding(message)
}
} catch {
return false
return .stopAndInvalidateSession
}
case .success:
return true
return .continueToReceive
case .failure:
return false
return .stopAndInvalidateSession
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,15 @@
//

import Foundation
import Amplify

final class WebSocketSession {
private let urlSessionWebSocketDelegate: Delegate
private let session: URLSession
private var task: URLSessionWebSocketTask?
private var receiveMessage: ((Result<URLSessionWebSocketTask.Message, Error>) -> Bool)?
private var receiveMessage: ((Result<URLSessionWebSocketTask.Message, Error>) -> WebSocketMessageResult)?
private var onSocketClosed: ((URLSessionWebSocketTask.CloseCode) -> Void)?
private var onServerDateReceived: ((Date?) -> Void)?

init() {
self.urlSessionWebSocketDelegate = Delegate()
Expand All @@ -23,7 +25,7 @@ final class WebSocketSession {
)
}

func onMessageReceived(_ receive: @escaping (Result<URLSessionWebSocketTask.Message, Error>) -> Bool) {
func onMessageReceived(_ receive: @escaping (Result<URLSessionWebSocketTask.Message, Error>) -> WebSocketMessageResult) {
self.receiveMessage = receive
}

Expand All @@ -34,25 +36,32 @@ final class WebSocketSession {
func onSocketOpened(_ onOpen: @escaping () -> Void) {
urlSessionWebSocketDelegate.onOpen = onOpen
}

func onServerDateReceived(_ onServerDateReceived: @escaping (Date?) -> Void) {
urlSessionWebSocketDelegate.onServerDateReceived = onServerDateReceived
}

func receive(shouldContinue: Bool) {
guard shouldContinue else {
func receive(result: WebSocketMessageResult) {
switch result {
case .continueToReceive:
task?.receive(completionHandler: { [weak self] result in
if let webSocketResult = self?.receiveMessage?(result) {
self?.receive(result: webSocketResult)
}
})
case .stopAndInvalidateSession:
session.finishTasksAndInvalidate()
case .invalidateSessionAndRetry(let url):
session.finishTasksAndInvalidate()
return
open(url: url)
}

task?.receive(completionHandler: { [weak self] result in
if let shouldContinue = self?.receiveMessage?(result) {
self?.receive(shouldContinue: shouldContinue)
}
})
}

func open(url: URL) {
var request = URLRequest(url: url)
request.setValue("no-store", forHTTPHeaderField: "Cache-Control")
task = session.webSocketTask(with: request)
receive(shouldContinue: true)
receive(result: .continueToReceive)
task?.resume()
}

Expand All @@ -77,10 +86,12 @@ final class WebSocketSession {
)
}

final class Delegate: NSObject, URLSessionWebSocketDelegate {
final class Delegate: NSObject, URLSessionWebSocketDelegate, URLSessionTaskDelegate {
var onClose: (URLSessionWebSocketTask.CloseCode) -> Void = { _ in }
var onOpen: () -> Void = {}
var onServerDateReceived: (Date?) -> Void = { _ in }

// MARK: - URLSessionWebSocketDelegate methods
func urlSession(
_ session: URLSession,
webSocketTask: URLSessionWebSocketTask,
Expand All @@ -97,5 +108,34 @@ final class WebSocketSession {
) {
onClose(closeCode)
}

// MARK: - URLSessionTaskDelegate methods
func urlSession(_ session: URLSession,
task: URLSessionTask,
didFinishCollecting metrics: URLSessionTaskMetrics
) {
guard let httpResponse = metrics.transactionMetrics.first?.response as? HTTPURLResponse,
let dateString = httpResponse.value(forHTTPHeaderField: "Date") else {
Amplify.log.verbose("\(#function): Couldn't find Date header in URLSession metrics")
onServerDateReceived(nil)
return
}

let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "EEE, d MMM yyyy HH:mm:ss z"
guard let serverDate = dateFormatter.date(from: dateString) else {
Amplify.log.verbose("\(#function): Error parsing Date header in expected format")
onServerDateReceived(nil)
return
}

onServerDateReceived(serverDate)
}
}

enum WebSocketMessageResult {
case continueToReceive
case stopAndInvalidateSession
case invalidateSessionAndRetry(url: URL)
}
}
4 changes: 0 additions & 4 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,6 @@

### Features

- **api**: add support for GraphQL filter attributeExists (#3484)

### Bug Fixes

- **api**: propagate connectionLost error from websocket client to sync engine (#3800)

## 2.36.0 (2024-07-18)
Expand Down
Loading

0 comments on commit 0dabc4f

Please sign in to comment.