Skip to content

TestFlight ์ž๋™ ๋ฐฐํฌ ํ…Œ์ŠคํŠธ #1

TestFlight ์ž๋™ ๋ฐฐํฌ ํ…Œ์ŠคํŠธ

TestFlight ์ž๋™ ๋ฐฐํฌ ํ…Œ์ŠคํŠธ #1

name: Distribution to TestFlight
on:
pull_request:
branches: [ release/* ]
jobs:
deploy:
name: ๐Ÿš€ Distribution to TestFlight Workflow
runs-on: macos-15 # ์ตœ์‹  macOS 15 ํ™˜๊ฒฝ์—์„œ ์‹คํ–‰
env:
## ํ”„๋กœ์ ํŠธ ์ด๋ฆ„์„ ๋ณ€์ˆ˜๋กœ ์„ค์ •
PROJECT_NAME: Poppool
# app archive ๋ฐ export ์— ์“ฐ์ผ ํ™˜๊ฒฝ ๋ณ€์ˆ˜ ์„ค์ •
XC_PROJECT: ${{ env.PROJECT_NAME }}/${{ env.PROJECT_NAME }}.xcodeproj

Check failure on line 16 in .github/workflows/deploy_on_release.yml

View workflow run for this annotation

GitHub Actions / Distribution to TestFlight

Invalid workflow file

The workflow is not valid. .github/workflows/deploy_on_release.yml (Line: 16, Col: 19): Unrecognized named-value: 'env'. Located at position 1 within expression: env.PROJECT_NAME .github/workflows/deploy_on_release.yml (Line: 17, Col: 18): Unrecognized named-value: 'env'. Located at position 1 within expression: env.PROJECT_NAME
XC_SCHEME: ${{ env.PROJECT_NAME }}
XC_ARCHIVE: ${{ env.PROJECT_NAME }}.xcarchive
# certificate
ENCRYPTED_CERT_FILE_PATH: ${{ '.github/secrets/certification.p12.gpg' }}
DECRYPTED_CERT_FILE_PATH: ${{ '.github/secrets/certification.p12' }}
CERT_ENCRYPTION_KEY: ${{ secrets.CERT_ENCRYPTION_PWD }} # gpg๋กœ ํŒŒ์ผ ์•”ํ˜ธํ™”ํ•  ๋•Œ ์‚ฌ์šฉํ•œ ์•”ํ˜ธ
# provisioning
ENCRYPTED_PROVISION_FILE_PATH: ${{ '.github/secrets/' }}${{ env.PROJECT_NAME }}GithubActions.mobileprovision.gpg
DECRYPTED_PROVISION_FILE_PATH: ${{ '.github/secrets/' }}${{ env.PROJECT_NAME }}GithubActions.mobileprovision
PROVISIONING_ENCRYPTION_KEY: ${{ secrets.PROVISION_ENCRYPTION_PWD }} # gpg๋กœ ํŒŒ์ผ ์•”ํ˜ธํ™”ํ•  ๋•Œ ์‚ฌ์šฉํ•œ ์•”ํ˜ธ
# certification export key
CERT_EXPORT_KEY: ${{ secrets.CERT_EXPORT_PWD }}
KEYCHAIN: ${{ 'test.keychain' }}
steps:
- name: Checkout Repository # ์ €์žฅ์†Œ ์ฝ”๋“œ ์ฒดํฌ์•„์›ƒ
uses: actions/checkout@v4
- name: ๐Ÿ› ๏ธ Set up Xcode # Xcode 16.2 ์„ ํƒ
run: sudo xcode-select -s /Applications/Xcode_16.2.app
- name: ๐Ÿ”‘ Configure Keychain # ํ‚ค์ฒด์ธ ์ดˆ๊ธฐํ™” -> ์ž„์‹œ ํ‚ค์ฒด์ธ ์ƒ์„ฑ
run: |
security create-keychain -p "" "$KEYCHAIN"
security list-keychains -s "$KEYCHAIN"
security default-keychain -s "$KEYCHAIN"
security unlock-keychain -p "" "$KEYCHAIN"
security set-keychain-settings
- name : ยฉ๏ธ Configure Code Signing
run: |
# certificate ๋ณตํ˜ธํ™”
gpg -d -o "$DECRYPTED_CERT_FILE_PATH" --pinentry-mode=loopback --passphrase "$CERT_ENCRYPTION_KEY" "$ENCRYPTED_CERT_FILE_PATH"
# provisioning ๋ณตํ˜ธํ™”
gpg -d -o "$DECRYPTED_PROVISION_FILE_PATH" --pinentry-mode=loopback --passphrase "$PROVISIONING_ENCRYPTION_KEY" "$ENCRYPTED_PROVISION_FILE_PATH"
# security๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ธ์ฆ์„œ์™€ ๊ฐœ์ธ ํ‚ค๋ฅผ ์ƒˆ๋กœ ๋งŒ๋“  ํ‚ค ์ฒด์ธ์œผ๋กœ ๊ฐ€์ ธ์˜ด
security import "$DECRYPTED_CERT_FILE_PATH" -k "$KEYCHAIN" -P "$CERT_EXPORT_KEY" -A
security set-key-partition-list -S apple-tool:,apple: -s -k "" "$KEYCHAIN"
# Xcode์—์„œ ์ฐพ์„ ์ˆ˜ ์žˆ๋Š” ํ”„๋กœ๋น„์ €๋‹ ํ”„๋กœํ•„ ์„ค์น˜ํ•˜๊ธฐ ์œ„ํ•ด ์šฐ์„  ํ”„๋กœ๋น„์ €๋‹ ๋””๋ ‰ํ† ๋ฆฌ๋ฅผ ์ƒ์„ฑ
mkdir -p "$HOME/Library/MobileDevice/Provisioning Profiles"
# ๋””๋ฒ„๊น… ์šฉ echo ๋ช…๋ น์–ด
echo `ls .github/secrets/*.mobileprovision`
# ๋ชจ๋“  ํ”„๋กœ๋น„์ €๋‹ ํ”„๋กœํŒŒ์ผ์„ rename ํ•˜๊ณ  ์œ„์—์„œ ๋งŒ๋“  ๋””๋ ‰ํ† ๋ฆฌ๋กœ ๋ณต์‚ฌํ•˜๋Š” ๊ณผ์ •
for PROVISION in `ls .github/secrets/*.mobileprovision`
do
UUID=`/usr/libexec/PlistBuddy -c 'Print :UUID' /dev/stdin <<< $(security cms -D -i ./$PROVISION)`
cp "./$PROVISION" "$HOME/Library/MobileDevice/Provisioning Profiles/$UUID.mobileprovision"
done
- name: โฌ‡๏ธ Archive app # ๋นŒ๋“œ ๋ฐ ์•„์นด์ด๋ธŒ
run: |
xcodebuild clean archive -project $XC_PROJECT -scheme $XC_SCHEME -configuration release -archivePath $XC_ARCHIVE
- name: โฌ†๏ธ Export app # export ๋ฅผ ํ†ตํ•ด ipa ํŒŒ์ผ ๋งŒ๋“ฆ
run: |
xcodebuild -exportArchive -archivePath $XC_ARCHIVE -exportOptionsPlist ExportOptions.plist -exportPath . -allowProvisioningUpdates
- name: ๐Ÿš€ Upload app to TestFlight # TestFlight์— ์•„์นด์ด๋ธŒ๋œ ์•ฑ ๋“ฑ๋ก
uses: apple-actions/upload-testflight-build@v1
with:
app-path: '${{ env.PROJECT_NAME }}.ipa'
issuer-id: ${{ secrets.APPSTORE_ISSUER_ID }}
api-key-id: ${{ secrets.APPSTORE_API_KEY_ID }}
api-private-key: ${{ secrets.APPSTORE_API_PRIVATE_KEY }}