Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
60 changes: 48 additions & 12 deletions .github/workflows/deliver-metadata.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,14 @@ on:
- 'ios/fastlane/metadata/**'
- 'ios/fastlane/Deliverfile'
workflow_dispatch:
inputs:
source_ref:
description: Git ref/SHA containing the metadata to deliver instead of the workflow ref
required: false
type: string

permissions:
contents: read
id-token: write

concurrency:
group: deliver-app-store-metadata
Expand All @@ -25,21 +29,51 @@ jobs:
runs-on: ${{ fromJSON(vars.RUNNER_LABELS_LINUX || '["ubuntu-latest"]') }}
steps:
- uses: actions/checkout@v4
with:
ref: ${{ github.event_name == 'workflow_dispatch' && inputs.source_ref || github.ref }}
fetch-depth: 0

- name: Clear runner AWS profile overrides
- name: Resolve checked-out metadata source
id: source
shell: bash
run: |
echo "AWS_PROFILE=" >> "$GITHUB_ENV"
echo "AWS_DEFAULT_PROFILE=" >> "$GITHUB_ENV"
set -euo pipefail
echo "sha=$(git rev-parse HEAD)" >> "$GITHUB_OUTPUT"
echo "ref=${{ github.event_name == 'workflow_dispatch' && inputs.source_ref || github.ref }}" >> "$GITHUB_OUTPUT"

- name: Configure AWS credentials via OIDC
uses: aws-actions/configure-aws-credentials@v4
with:
role-to-assume: ${{ secrets.AWS_RELEASE_ROLE_ARN }}
aws-region: us-east-1
unset-current-credentials: true
- name: Write App Store Connect credentials
shell: bash
env:
ASC_KEY_ID: ${{ secrets.ASC_KEY_ID }}
ASC_ISSUER_ID: ${{ secrets.ASC_ISSUER_ID }}
ASC_PRIVATE_KEY: ${{ secrets.ASC_PRIVATE_KEY }}
run: |
set -euo pipefail
: "${ASC_KEY_ID:?ASC_KEY_ID secret is required}"
: "${ASC_ISSUER_ID:?ASC_ISSUER_ID secret is required}"
: "${ASC_PRIVATE_KEY:?ASC_PRIVATE_KEY secret is required}"

- name: Fetch App Store Connect credentials
run: scripts/runner/fetch_asc_secret.sh
mkdir -p "$HOME/.appstoreconnect/private_keys"
p8_path="$HOME/.appstoreconnect/private_keys/AuthKey_${ASC_KEY_ID}.p8"
printf '%s' "$ASC_PRIVATE_KEY" > "$p8_path"
chmod 600 "$p8_path"

jq -n \
--arg key_id "$ASC_KEY_ID" \
--arg issuer_id "$ASC_ISSUER_ID" \
--arg key "$ASC_PRIVATE_KEY" \
'{
key_id: $key_id,
issuer_id: $issuer_id,
key: $key,
in_house: false
}' > /tmp/asc_api_key.json
chmod 600 /tmp/asc_api_key.json

{
echo "ASC_KEY_ID=$ASC_KEY_ID"
echo "ASC_ISSUER_ID=$ASC_ISSUER_ID"
} >> "$GITHUB_ENV"

- name: Set up Ruby and Bundler
if: ${{ !contains(fromJSON(vars.RUNNER_LABELS_LINUX || '["ubuntu-latest"]'), 'self-hosted') }}
Expand Down Expand Up @@ -67,6 +101,8 @@ jobs:
{
echo "## Metadata delivered to App Store Connect"
echo ""
echo "- Metadata source ref: ${{ steps.source.outputs.ref }}"
echo "- Metadata source commit: ${{ steps.source.outputs.sha }}"
echo "Updated App Store metadata and screenshots only."
echo "Binary upload and App Review submission were not touched."
} >> "$GITHUB_STEP_SUMMARY"
100 changes: 100 additions & 0 deletions .github/workflows/release-app-store.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
name: Release App Store Version

on:
workflow_dispatch:
inputs:
tag:
description: Release tag to publish
required: true
type: string
dry_run:
description: Validate release readiness without publishing or deleting tags
required: true
type: boolean
default: true

permissions:
contents: write

concurrency:
group: app-store-version-release
cancel-in-progress: false

jobs:
release:
name: Release approved App Store version
runs-on: ${{ fromJSON(vars.RUNNER_LABELS_LINUX || '["ubuntu-latest"]') }}
environment: ${{ vars.APPROVAL_ENVIRONMENT || 'app-store-release' }}
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0

- name: Resolve tag and version
id: resolve-tag
shell: bash
run: |
set -euo pipefail
TAG="${{ inputs.tag }}"
VERSION="${TAG#app/v}"
VERSION="${VERSION#v}"
VERSION="${VERSION%%-rc.*}"
echo "tag=$TAG" >> "$GITHUB_OUTPUT"
echo "version=$VERSION" >> "$GITHUB_OUTPUT"

- name: Write App Store Connect credentials
shell: bash
env:
ASC_KEY_ID: ${{ secrets.ASC_KEY_ID }}
ASC_ISSUER_ID: ${{ secrets.ASC_ISSUER_ID }}
ASC_PRIVATE_KEY: ${{ secrets.ASC_PRIVATE_KEY }}
run: |
set -euo pipefail
: "${ASC_KEY_ID:?ASC_KEY_ID secret is required}"
: "${ASC_ISSUER_ID:?ASC_ISSUER_ID secret is required}"
: "${ASC_PRIVATE_KEY:?ASC_PRIVATE_KEY secret is required}"

mkdir -p "$HOME/.appstoreconnect/private_keys"
p8_path="$HOME/.appstoreconnect/private_keys/AuthKey_${ASC_KEY_ID}.p8"
printf '%s' "$ASC_PRIVATE_KEY" > "$p8_path"
chmod 600 "$p8_path"

{
echo "ASC_KEY_ID=$ASC_KEY_ID"
echo "ASC_ISSUER_ID=$ASC_ISSUER_ID"
} >> "$GITHUB_ENV"

- name: Install Python dependencies
run: |
python3 -m venv .venv-release
.venv-release/bin/python -m pip install --upgrade pip --quiet
.venv-release/bin/python -m pip install PyJWT requests cryptography --quiet

- name: Release App Store version
shell: bash
env:
VERSION: ${{ steps.resolve-tag.outputs.version }}
run: |
args=()
if [ "${{ inputs.dry_run }}" = "true" ]; then
args+=(--dry-run)
fi

.venv-release/bin/python scripts/release/release_app_store_version.py \
--key-id "$ASC_KEY_ID" \
--issuer-id "$ASC_ISSUER_ID" \
--private-key-path "$HOME/.appstoreconnect/private_keys/AuthKey_${ASC_KEY_ID}.p8" \
--app-id "${{ vars.APPLE_APP_ID }}" \
--version "$VERSION" \
"${args[@]}"

- name: Summary
run: |
{
echo "## App Store release workflow complete"
echo ""
echo "- Tag: ${{ steps.resolve-tag.outputs.tag }}"
echo "- Version: ${{ steps.resolve-tag.outputs.version }}"
echo "- Dry run: ${{ inputs.dry_run }}"
echo "- Cleanup scope: testflight/${{ steps.resolve-tag.outputs.version }}/build-*"
} >> "$GITHUB_STEP_SUMMARY"
Loading
Loading