스트리밍은 대부분의 브라우저와
Developer 앱에서 사용할 수 있습니다.
-
Xcode Cloud 워크플로 확장하기
개발 요구사항에 맞춰 Xcode Cloud를 유연하게 맞춤화하는 방법을 알아보세요. 워크플로를 간소화하는 방법을 소개하고 시작 조건, 맞춤형 앨리어스, 맞춤형 스크립트, 웹훅, App Store Connect API를 사용하여 테스트 및 배포를 자동화하는 방법을 설명합니다.
챕터
- 0:00 - Introduction
- 1:08 - Essential Workflow Concepts
- 3:00 - Scale your workflows
- 11:38 - Connect other systems
- 12:33 - App Store Connect API
- 16:35 - Webhooks
- 20:33 - Wrap up
리소스
- Configuring start conditions
- Configuring webhooks in Xcode Cloud
- Environment variable reference
- Forum: Developer Tools & Services
- Sharing build configurations across Xcode Cloud workflows
- Writing custom build scripts
관련 비디오
WWDC23
WWDC21
-
다운로드
안녕하세요, 저는 Daniel입니다 후반부에는 제 동료 Colin이 함께합니다 오늘은 워크플로의 규모를 확장하고 확대할 수 있는 Xcode Cloud의 강력하고 유연한 기능을 설명합니다 Xcode Cloud는 Xcode에서 기본 제공되는 지속적 통합 및 배포 서비스로 App Store Connect에서도 사용 가능합니다 Xcode Cloud는 Apple 개발자를 위해 설계되었으며, 고품질 앱의 개발과 배포를 가속합니다 Xcode Cloud의 클라우드 기반 도구로 앱을 빌드하고 자동화된 테스트를 병렬 실행하고 테스터에게 앱을 배포하고 사용자 피드백을 확인 및 관리하여 탁월한 앱을 빌드할 수 있습니다
이 세션에서는 Xcode Cloud 워크플로를 확장하는 방법을 살펴봅니다 먼저 몇 가지 필수적인 워크플로 개념을 검토합니다 다음으로 앱이 성장함에 따라 워크플로를 확장하는 방법을 보여 드리겠습니다 마지막으로는 워크플로를 확장하여 Xcode Cloud가 아닌 시스템으로 작업해 봅니다
그럼 몇 가지 필수적인 워크플로 개념을 검토해 볼게요 모든 Apple Developer Program 멤버십 이용 시 월별로 25시간의 빌드 시간이 제공됩니다 이 세션이 마무리되면 처음 시작하거나 더 유연한 워크플로를 구축하는 데 필요한 도구를 확보할 수 있습니다
방금 살펴본 것처럼 개발 시 Xcode Cloud로 많은 작업을 수행할 수 있음에도 모든 사항이 간단한 워크플로에서 시작됩니다 워크플로는 네 개의 요소로 구성됩니다 환경 시작 조건 빌드 작업 사후 작업입니다
환경은 워크플로의 환경 변수를 정의하는 곳입니다 워크플로를 실행할 때 워크플로에서 사용할 Xcode와 macOS 버전을 결정하는 곳이기도 합니다 특정 버전을 선택하거나 최신 릴리스와 같이 유용한 앨리어스 모음에서 선택할 수 있습니다
시작 조건은 워크플로 실행 시기를 정의합니다 소스 제어 이벤트에 응답하도록 선택할 수 있으며 브랜치, Pull 요청, git 태그 업데이트 등을 예로 들 수 있습니다 일정 설정도 선택할 수 있으므로 특정 요일과 시간에 워크플로가 실행되도록 지정할 수 있어요 수동으로만 실행되도록 수동 시작 조건을 선택하는 것도 가능합니다
빌드 작업에서는 소스 코드로 수행할 수 있는 Xcode Cloud 작업을 설명하고 그 중 하나 이상을 사용하여 워크플로를 구성할 수 있습니다 앱 빌드를 선택하고
테스트를 실행하고 앱을 분석하거나 아카이브하여 배포를 준비합니다 마지막으로 사후 작업은 빌드 작업이 완료된 후에 일어나는 작업을 정의합니다 빌드가 완료되면 Slack을 통해 팀에 알리거나 아카이드된 앱으로 공증이나 TestFlight를 배포하는 등의 작업을 할 수 있습니다
대부분의 경우 간단한 워크플로만으로도 많은 작업을 수행하기에 충분합니다 하지만 워크플로가 효과적이기 때문에 앱이 성장함에 따라 요구 사항에 맞게 확장할 수 있습니다 최근에 작업하고 있는 앱에 몇 가지 기능을 추가하였으므로 서비스에서 데이터를 가져올 수 있습니다 기존 Xcode Cloud 워크플로는 코드가 기본 브랜치에서 푸시될 때 시작됩니다 최신 변경 사항을 빌드한 다음 테스트가 실행되고 마지막으로 변경 사항이 TestFlight상의 테스터에게 전달됩니다
테스트 모음에는 모의 데이터를 기반으로 한 UI 테스트와 단위가 혼합되어 있으며 앱에 포함된 UI와 논리를 실습하기에 좋습니다 하지만 이제 앱이 서비스에 의존적이기 때문에 테스트 서버와 통신하는 몇 가지 통합 테스트를 추가했습니다
통합 테스트는 앱이 해당 종속성을 토대로 처음부터 끝까지 작동하는지 확인하는 유용한 방법입니다 하지만 이 경우에는 다른 테스트보다 실행하는 데 더 많은 시간과 리소스가 필요하여 앱이 제어할 수 없는 네트워크 상태 등의 문제로 인해 영향을 받을 수 있습니다 통합 테스트를 실행하는 워크플로를 구성하고 싶지만 워크플로가 서버에 의존하여 실제 네트워크 요청을 생성하기 때문에 이 워크플로가 실행되는 시점을 더 세밀하게 제어할 수 있는 기능이 필요합니다 Xcode 15.1의 새로운 기능으로 수동 시작 조건을 사용하여 워크플로가 수동으로 시작되도록 구성할 수 있습니다 바로 방법을 알아 보겠습니다 먼저 새 테스트 계획만 실행하는 새 워크플로를 만듭니다
여기서는 시간을 절약하기 위해 기존 워크플로를 복제하겠습니다
워크플로가 표시되면 Cloud 보고서 탐색기에 있는 앱을 보조 클릭하고 Manage Workflows를 선택합니다
Manage Workflows 뷰에서 기존의 워크플로를 보조 클릭하고 Duplicate 작업을 선택합니다 그러면 새 워크플로가 워크플로 편집기에서 열립니다 워크플로 이름을 Integration Tests로 변경하고 Description란은 비워 둡니다 다음으로 수동 시작 조건을 추가하고 기존 버전은 제거합니다
이제 사용자가 지시할 때만 워크플로가 시작되고 다른 이벤트에는 반응하지 않습니다 기본 옵션을 적용하여 모든 브랜치와 시작 조건을 연결하되 브랜치나 PR, git 태그를 지정하여 이 시작 조건을 연결할 수 있는 git 참조에 대한 정보를 더 구체화할 수도 있습니다
테스트 작업을 변경하여 IntegrationTests 테스트 계획을 실행해 보겠습니다
지금은 이 워크플로가 완료되고 아무 작업도 수행되지 않아야 하므로 사후 작업을 제거하고 ’Save’를 클릭합니다
물론 Environment 탭에 명시된 다른 버전의 Xcode와 macOS로 실행하여 워크플로를 구성할 수 있습니다 하지만 여기서는 두 워크플로가 항상 동일한 버전으로 실행됩니다
맞춤형 앨리어스는 Xcode 15.3의 새로운 기능입니다 Xcode Cloud는 이미 최신 릴리스와 같이 여러분이 보셨을 수도 있는 몇 가지 앨리어스를 제공하며 지원되는 최신 버전에서 워크플로가 실행되도록 보장해 줍니다 이제 팀에 맞게 자체 앨리어스를 정의할 수 있습니다
하나 이상의 워크플로에서 자체 앨리어스를 사용하면 해당 워크플로가 앨리어스에 명시된 Xcode나 macOS 버전을 사용해 실행됩니다 즉 앨리어스가 업데이트되면 해당 버전을 사용하는 모든 워크플로가 업데이트된 값으로 실행됩니다 방금 생성한 새 워크플로에서 이 기능을 사용해 봅니다
주어진 앱에서 모든 맞춤형 앨리어스를 보려면 탐색기에서 앱을 보조 클릭하고 Manage Custom Aliases를 선택합니다
더하기(+) 버튼을 클릭하여 새 Xcode 앨리어스를 만듭니다 이렇게 하면 맞춤형 앨리어스 편집기가 열립니다 이 창에서 맞춤형 앨리어스 이름을 지정하고 앨리어스가 참조하는 Xcode 버전을 선택합니다 여기서는 Team Preference로 이름을 지정하고 Xcode 15.3을 선택합니다
’Save’를 클릭하고 macOS 앨리어스 역시 동일하게 입력합니다
워크플로에 앨리어스를 적용하려면 다시 워크플로 관리 뷰로 이동하여 Integration Tests 워크플로를 열어 Environment 탭으로 이동합니다
이제 Xcode 버전 드롭다운 메뉴에서 맞춤형 앨리어스를 확인할 수 있습니다 앨리어스를 선택하고 macOS에서도 동일하게 적용해 봅니다
맞춤형 앨리어스를 빠르게 생성하거나 관리하려면 버전 선택기 드롭다운 메뉴에서 선택하거나 통합 메뉴 항목에서 선택하면 됩니다 드디어 첫 번째 워크플로로 다시 이동하여 새 앨리어스에 사용할 Xcode와 macOS 버전을 업데이트합니다
완벽하네요! 이제 앨리어스를 새 버전으로 업데이트할 때마다 두 워크플로에 해당 변경 사항이 적용됩니다
맞춤형 앨리어스 사용 방법을 자세히 알아볼 수 있는 문서가 준비되어 있습니다
통합 테스트는 Xcode Cloud에서 변경 사항을 적용하지 않고 잘 작동할 테지만 테스트 서버가 온라인 상태일 경우에만 실행되도록 하면 더 스마트하게 만들 수 있습니다 이를 구현하기 위해 Xcode Cloud의 또 다른 멋진 기능을 활용하여 프로젝트에 맞춤형 스크립트를 추가해 볼게요
리포지토리 내부에 맞춤형 스크립트를 정의하여 빌드의 특정 시점에 실행되도록 지정할 수 있습니다
특정 시점은 리포지토리가 복제된 후 xcodebuild가 실행되기 전이나 xcodebuild가 실행된 후입니다
맞춤형 스크립트에 대한 자세한 내용은 ‘고급 Xcode Cloud 워크플로 사용자 지정’을 확인하세요
워크플로에 정의된 모든 환경 변수와 Xcode Cloud에서 제공하는 환경 변수는 이러한 스크립트에서 사용할 수 있습니다 지금은 맞춤형 스크립트에 두 가지를 사용해 볼게요
사용할 수 있는 환경 변수 전체 목록을 보려면 문서에 나와 있는 ’환경 변수 참조’ 페이지로 이동하세요
Xcode Cloud는 모든 맞춤형 스크립트가 프로젝트 루트에 있는 ci_scripts 폴더에 있을 거라 예측합니다
스크립트 파일 이름에 따라 빌드에서 실행될 시점이 결정됩니다
이 시나리오에서는 테스트가 실행되기 바로 전에 스크립트가 실행되도록 합니다
Xcode의 경우 프로젝트 탐색기에서 프로젝트를 보조 클릭하여 스크립트 폴더를 생성합니다
폴더에 새 스크립트 파일을 추가하고 ci_pre_xcodebuild.sh로 이름을 지정하여 테스트 전에 실행되도록 설정합니다
통합 테스트에 대해서만 작업을 진행하고 싶으므로 몇 가지 논리를 추가하여 빌드 작업과 workflowID에 대한 환경 변수를 확인합니다
여기서 스크립트는 테스트 빌드 작업이 실행 중인지 확인하고 워크플로가 식별자와 일치하는지 확인합니다 워크플로의 ID를 가져오려면 Cloud 보고서 탐색기로 이동하여 워크플로를 보조 클릭하고 Copy Workflow ID를 선택하기만 하면 됩니다
이제 작업을 마쳤으니 스크립트로 돌아가서 붙여넣습니다
이 블록 내부에 curl을 사용하여 서버의 상태 확인 엔드포인트를 호출하고 실패 시 자세한 오류 로그가 출력되도록 할 수 있습니다
set -e shell 옵션을 지정하면 오류가 발생할 경우 이 스크립트가 즉시 종료되고 워크플로가 해당 지점에서 중지되며 이 결과는 서버에 접할 수 없을 때 우리가 원하는 결과와 정확히 일치합니다
Xcode Cloud 빌드는 일시적인 태스크 작업자에서 실행되므로 호스트가 사용하는 IP 주소의 범위가 다르다는 점을 참고하세요 저는 이미 Xcode Cloud가 서버와 통신할 수 있도록 필요한 IP 주소 범위를 서버의 방화벽 인바운드 허용 목록에 추가했습니다
허용할 IP 주소의 세부 정보를 가져오려면 ‘Xcode Cloud 사용을 위한 요구 사항’ 문서 페이지를 참고하세요 여러분은 방금 수동 시작 조건을 사용하여 통합 테스트 용도로 새 워크플로를 빌드하고 맞춤형 앨리어스를 사용하여 워크플로가 macOS와 Xcode 버전과 동기화되도록 했습니다 또한 맞춤형 스크립트 기능으로 테스트를 더 스마트하게 만들고 테스트 서버에 접근할 수 없는 경우 실패를 단축했습니다 Xcode Cloud를 다른 시스템과 연결하고 워크플로를 한층 강화하는 방법에 대해 Colin이 설명할 예정입니다
Daniel, 고맙습니다 이제 워크플로 개념과 확장 방법을 알아보았으니 지금까지 진행한 작업을 토대로 Xcode Cloud가 어떻게 외부의 시스템과 연결되는지 살펴보겠습니다
앞서 Daniel이 언급한 것처럼 이제 저희 앱은 서비스에 의존적입니다 이 새로운 종속성에 따라 추가 위험이 수반되며 누군가가 서버에 코드 변경을 푸시하여 앱을 손상시킬 수 있습니다
이러한 일부 위험을 완화하기 위해 새로운 통합 테스트 워크플로를 실행할 수 있어요 이 과정에서 생성되는 테스트 결과를 통해 앱이 최신 서버 변경 사항과 호환되는지 여부를 알 수 있습니다 지금은 워크플로가 수동으로만 실행되지만 App Store Connect API를 사용하여 테스트 서버에 새 변경 사항이 생길 때마다 자동으로 빌드를 시작하는 것이 가능합니다
App Store Connect API를 사용하면 다양한 App Store Connect 작업을 자동화할 수 있으며 Xcode Cloud와 관련된 작업 역시 자동화할 수 있습니다 이러한 엔드포인트와 이를 호출하는 방법에 대한 자세한 내용은 문서에서 확인 가능합니다
역방향으로 작업하여 App Store Connect API로 통합 테스트 워크로드를 실행하는 데 필요한 사항을 살펴봅니다
CiBuildRuns 엔드포인트로 새 Xcode Cloud 빌드를 생성할 수 있습니다
호출하려면 실행하려는 워크플로의 식별자와 빌드하려는 gitReference를 지정해야 합니다 우리는 통합 테스트 워크플로의 ID를 알고 있지만 빌드하려는 브랜치의 gitReference는 알지 못합니다 이 정보는 ScmRepositories 엔드포인트를 사용하여 찾을 수 있어요 repositoryID로 이 엔드포인트를 호출하여 해당 리포지토리와 연결된 모든 브랜치, 태그 Pull 요청을 가져옵니다 하지만 먼저 워크플로에서 사용하는 repositoryID를 알아야 해요 이 정보는 CiWorkflows 리소스에 포함되어 있으며 workflowID를 사용하여 쿼리할 수 있습니다
원하는 빌드를 만들려면 스크립트에 총 세 번의 API 호출이 생성되어야 합니다
App Store Connect API가 OpenAPI를 사용해 지정되므로 코드 생성기를 사용하여 엔드포인트별로 확실하게 유형이 지정된 Swift 코드를 생성할 수 있습니다 이 데모에서는 구현을 집중적으로 살펴보지만 제가 사용하는 오픈 소스 코드 생성기는 ‘Swift OpenAPI 생성기 알아보기’에서 확인하실 수 있습니다 빌드를 생성하기 위해 세 번의 API 호출이 필요하므로 편의상 생성된 API 클라이언트에 몇 가지 확장 프로그램을 추가하겠습니다
필요한 함수는 workflowID를 매개변수로 받고 연결된 CiWorkflows 리소스를 가져온 다음 repositoryID를 반환하는 함수입니다
다음으로 해당 repositoryID를 우리가 빌드하려는 gitReferenceID로 변환할 방법이 필요합니다 이 작업은 SCMRepositories 엔드포인트로 수행할 수 있어요 리포지토리와 연결된 모든 gitReferences를 가져오고 지정된 이름이 사용된 브랜치의 gitReferenceID가 반환되죠
마지막으로 새 빌드를 시작하려고 합니다 그러려면 workflowID와 gitReferenceID가 필요하며 이 값을 ciBuildRuns 엔드포인트에 전달할 수 있습니다
이제 모든 내용을 종합해 볼게요 먼저 RepoID 함수를 호출하는 데 통합 테스트 워크플로에 해당하는 workflowID를 사용합니다
다음으로 빌드하려는 브랜치 이름을 사용하는 branchID를 호출합니다 이 경우에는 ’main’ 값을 사용하겠습니다
마지막으로 workflowID와 gitReferenceID로 startBuild를 호출하고 스크립트를 완성합니다
App Store Connect API로 시작하는 빌드는 수동으로 간주되므로 빌드하고 있는 참조와 일치하는 수동 시작 조건이 설정되어 있는지 확인해야 한다는 점을 참고하시기 바랍니다 여기서는 Daniel이 이미 모든 브랜치와 일치하는 수동 시작 조건을 사용하여 이 워크플로를 설정한 덕분에 문제될 것이 없습니다
스크립트가 완성되면 이제 새 서버 코드가 푸시될 때마다 테스트 결과를 생성할 수 있습니다 여기서 작업을 중단할 수 있겠지만 테스트 결과로 추가 작업을 수행하고 싶을 수도 있어요
지금까지 수행한 작업을 프로덕션 환경에 연결하여 서버 변경 사항이 테스트 환경에서 검증된 후 배포되도록 하려고 합니다
직접 테스트 결과를 확인하고 필요에 따라 수동으로 프로덕션에 배포할 수 있지만 더 나은 방법이 있습니다
대신 Xcode Cloud 웹훅 기능을 활용하여 테스트 결과를 배포 서비스에 연결한 다음 테스트가 완료되면 서버 변경 사항이 자동으로 프로덕션에 푸시됩니다
웹훅을 사용하면 서비스가 빌드 이벤트가 발생하면 응답하도록 지원하므로 Xcode Cloud를 개발 과정에서 활용하는 기타 서비스 및 도구에 통합할 수 있습니다 웹훅과 웹훅 구성 방법에 대한 자세한 내용은 문서에서 확인하실 수 있습니다
웹훅을 수신하고 응답하는 데 필요한 사항은 HTTP 서버입니다 간단한 프로젝트를 설정할 수 있으며 Vapor나 Hummingbird 프레임워크를 사용해 Swift on Server로 몇 가지 단계만 거치면 됩니다 이 데모에서 집중하려는 것은 구현이므로 이미 Vapor 서버를 설정할 때 웹훅을 수신할 수 있는 엔드포인트를 포함했습니다 웹훅을 구성하면 Xcode Cloud가 엔드포인트에 요청을 전송하며 여기에 다양한 빌드 이벤트에 대한 상세한 정보가 담긴 JSON 페이로드가 포함됩니다
여기에 WebhookPayload 구조체를 정의했으며 관심 있는 필드를 포함했습니다 이 시나리오에서 필요한 사항은 workflowID, buildID 빌드 executionProgress 빌드 completionState입니다
이 구조체를 사용하여 웹훅 요청을 디코딩하고 이로써 페이로드에서 필드를 쉽게 추출할 수 있습니다
다음으로 일부 로직을 추가하여 페이로드의 workflowID를 통합 테스트 워크플로의 workflowID와 비교합니다
두 개의 유사한 필드는 빌드 이벤트의 상태를 설명해 줍니다 executionProgress는 빌드가 실행 중인지 완료되었는지를 설명하고 completionStatus는 빌드의 성공 혹은 실패 여부를 설명합니다 if 구문이 두 가지를 모두 확인하도록 업데이트하여 빌드가 성공적으로 완료되었는지 확인하겠습니다
이 구문의 본문에서 통합 테스트가 통과된 것을 배포 서비스에 전달하고 buildID를 전송하겠습니다 배포 서비스는 이 정보를 다른 확인 작업과 함께 활용하여 서버 변경 사항을 승인하고 프로덕션에 배포할 수 있습니다
마지막 작업으로 Xcode Cloud에 빌드 이벤트를 웹훅으로 보내도록 지시합니다 이 작업은 App Store Connect의 Xcode Cloud 뷰에서 진행할 수 있습니다
앱을 선택하고 Settings로 이동하여 ’Webhooks’ 탭을 클릭합니다
더하기(+) 버튼을 클릭하여 새 웹훅을 구성합니다
이름을 지정하고 리스너의 URL을 추가합니다
웹훅을 설정함으로써 Xcode Cloud를 통해 서버 변경 사항을 연결할 모든 구성 요소가 갖춰졌습니다 지금까지 진행한 작업을 복습해 보겠습니다
새로운 코드 변경 사항이 서비스의 테스트 환경에 배포될 때마다 App Store Connect API를 호출하여 통합 테스트 워크플로의 빌드를 시작합니다 이렇게 하면 앱과 테스트 서버 간의 통합을 검증하는 테스트가 실행됩니다
결과가 웹훅 리스너에서 처리되고 모든 테스트를 통과하면 변경 사항이 프로덕션에 배포됩니다
모든 항목이 통과되는 경우 파이프라인이 코드 푸시부터 프로덕션 배포에 이르기까지 전부 자동화됩니다
하지만 서버 변경 사항이 푸시되어 앱에 문제가 발생하는 경우가 있습니다
통합 테스트가 실패하고 웹훅 리스너는 변경 사항이 프로덕션에 배포되는 일이 발생하지 않도록 방지할 겁니다 정확히 의도했던 대로죠
지금까지 서버 코드 변경에 대해 이야기하고 있습니다 변경 사항을 푸시한 팀 멤버가 자신의 컴퓨터에 Xcode를 설치하지 않았을 수도 있습니다 하지만 Xcode Cloud가 App Store Connect 내에 통합되어 있기 때문에 여전히 브라우저에서 문제를 보고 조사할 수 있습니다
App Store Connect에서는 예상과는 다르게 실행된 빌드 결과를 볼 수 있습니다 Actions 섹션은 IntegrationTests 작업에 문제가 있는 것을 분명하게 보여 줍니다
Tests 섹션을 클릭하면 테스트 보고서가 열립니다
App Store Connect에서도 Xcode에서 기대할 수 있는 모든 작업을 보고 수행할 수 있습니다 테스트 상태별로 필터링하고 테스트 모음별로 검색하며 각 테스트에 관한 자세한 정보를 볼 수 있죠 이 경우에는 서버에서 반환되는 데이터에 문제가 있다는 사실을 확인할 수 있습니다
추가 조사가 필요하면 사이드바에서 ’Artifacts’를 클릭하여 빌드와 관련된 다양한 파일을 다운로드합니다 Xcode 로그와 충돌 보고서처럼요 이 세션에서 많은 내용을 다루었으나 Xcode Cloud 워크플로를 확장할 수 있는 방법 중 몇 가지를 소개한 것에 불과합니다
수동 시작 조건 맞춤형 앨리어스, 맞춤형 스크립트를 사용해 팀의 워크플로를 확장하고 다른 시스템에 워크플로를 통합하기 위해 App Store Connect API와 웹훅을 사용했습니다
’Xcode Cloud에서의 실용적인 작업 흐름 만들기’ ‘Xcode Cloud 소개’ 등의 다른 세션을 확인하여 Xcode Cloud로 팀의 CI 프로세스를 강화하는 방법에 대해 알아보세요
이 시간을 통해 얻은 몇 가지 새로운 아이디어로 여러분의 워크로드에 이러한 개념을 적용할 수 있는 방법을 찾으시기 바랍니다 시청해 주셔서 감사합니다!
-
-
10:02 - Custom Script
#!/bin/sh set -e if [[ $CI_XCODEBUILD_ACTION == "test-without-building" && $CI_WORKFLOW_ID == "82D89C93-B69C-46B5-A794-A2BCFD3EE487" ]] then curl https://example.com/health --fail fi
-
14:01 - App Store Connect API - Client Extension
extension Client { func repoID(workflowID: String) async throws -> String { return try await ciWorkflowsGetInstance( path: .init(id: workflowID), query: .init(include: [.repository]) ).ok.body.json.data.relationships!.repository!.data!.id } func branchID(repoID: String, name: String) async throws -> String { return try await scmRepositoriesGitReferencesGetToManyRelated( path: .init(id: repoID) ) .ok.body.json.data .filter { $0.attributes!.kind == .BRANCH && $0.attributes!.name == name } .first!.id } func startBuild(workflowID: String, gitReferenceID: String) async throws { _ = try await ciBuildRunsCreateInstance( body: .json(.init( data: .init( _type: .ciBuildRuns, relationships: .init( workflow: .init(data: .init( _type: .ciWorkflows, id: workflowID )), sourceBranchOrTag: .init(data: .init( _type: .scmGitReferences, id: gitReferenceID )) ) ) )) ).created } }
-
14:43 - App Store Connect API - Main Function
static func main() async throws { let client = try Client( serverURL: Servers.server1(), configuration: .init(dateTranscoder: .iso8601WithFractionalSeconds), transport: URLSessionTransport(), middlewares: [AuthMiddleware(token: ProcessInfo.processInfo.environment["TOKEN"]!)] ) let workflowID = "82D89C93-B69C-46B5-A794-A2BCFD3EE487" let repoID = try await client.repoID(workflowID: workflowID) let branchName = "main" let branchID = try await client.branchID(repoID: repoID, name: branchName) try await client.startBuild(workflowID: workflowID, gitReferenceID: branchID) }
-
17:09 - Webhook Handler Implementation
struct WebhookPayload: Content { let ciWorkflow: CiWorkflow let ciBuildRun: CiBuildRun struct CiWorkflow: Content { let id: String } struct CiBuildRun: Content { let id: String let executionProgress: String let completionStatus: String } } func routes(_ app: Application) throws { let deploymentService = ExampleDeploymentClient() let workflowID = "82D89C93-B69C-46B5-A794-A2BCFD3EE487" app.post("webhook") { req async throws -> HTTPStatus in return HTTPStatus.ok } }
-
-
찾고 계신 콘텐츠가 있나요? 위에 주제를 입력하고 원하는 내용을 바로 검색해 보세요.
쿼리를 제출하는 중에 오류가 발생했습니다. 인터넷 연결을 확인하고 다시 시도해 주세요.