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
5 changes: 5 additions & 0 deletions .github/actionlint.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
self-hosted-runner:
labels:
# GitHub-hosted public preview label announced in actions/runner-images#14404.
# Remove this override after actionlint recognizes the hosted label.
- xcode-27
67 changes: 67 additions & 0 deletions .github/scripts/validate-release-policy.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
#!/usr/bin/env bash
Comment thread
Shahroz16 marked this conversation as resolved.
set -euo pipefail

: "${PR_TITLE:?PR_TITLE is required}"
: "${BASE_SHA:?BASE_SHA is required}"
: "${HEAD_SHA:?HEAD_SHA is required}"
is_release_message() {
local message="$1"
local header
header=$(sed -n '/[^[:space:]]/{p;q;}' <<< "$message")

case "$header" in
fix:*|fix\(*|feat:*|feat\(*|perf:*|perf\(*|revert:*|revert\(*|Revert\ \"*)
return 0
;;
esac

if grep -Eq '^[[:alpha:]]+(\([^)]*\))?!:' <<< "$header"; then
return 0
fi

if grep -Eq '(^|[[:space:]])(BREAKING CHANGES?:|BREAKING-CHANGE:)' <<< "$message"; then
return 0
fi

if grep -Eq '(^|[[:space:]])This reverts commit[[:space:]]' <<< "$message"; then
return 0
fi

return 1
}

pr_release=false
commit_release=false

if is_release_message "$PR_TITLE"; then
pr_release=true
fi

git cat-file -e "$BASE_SHA^{commit}"
git cat-file -e "$HEAD_SHA^{commit}"
commit_messages_file=$(mktemp)
trap 'rm -f "$commit_messages_file"' EXIT
git log --format='%B%x00' "$BASE_SHA..$HEAD_SHA" > "$commit_messages_file"

while IFS= read -r -d '' commit_message; do
if is_release_message "$commit_message"; then
commit_release=true
break
fi
done < "$commit_messages_file"

full_validation=false

if [[ "$pr_release" == 'true' || "$commit_release" == 'true' || "${CI_FULL:-false}" == 'true' ]]; then
full_validation=true
fi

if [[ -n "${GITHUB_OUTPUT:-}" ]]; then
{
echo "pr_release=$pr_release"
echo "commit_release=$commit_release"
echo "full_validation=$full_validation"
} >> "$GITHUB_OUTPUT"
fi

echo "Distribution policy classified (pr_release=$pr_release, commit_release=$commit_release, full_validation=$full_validation)."
11 changes: 9 additions & 2 deletions .github/workflows/api-validation.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,13 @@
name: Public API change Validation

on: [pull_request]
on:
pull_request:
paths-ignore:
- '**/*.md'

concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

jobs:
validate-api:
Expand All @@ -18,4 +25,4 @@ jobs:
run: npm run prepare

- name: Validate API
run: npx api-extractor run
run: npx api-extractor run
84 changes: 67 additions & 17 deletions .github/workflows/build-sample-app.yml
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,11 @@ on:
description: "Name of the platform in all upper case (IOS or ANDROID)"
required: true
type: string
should_distribute:
description: "Whether to sign and publish the sample app"
required: false
default: true
type: boolean

outputs:
sdk_version_name:
Expand Down Expand Up @@ -76,15 +81,26 @@ jobs:
# Copy the tracked project file to the root of the repository
cp -R SampleApp.xcodeproj.tracked SampleApp.xcodeproj

- name: Test deep-link acknowledgement state
if: ${{ inputs.platform == 'ios' && inputs.app_name == 'APN' }}
shell: bash
working-directory: .
run: |
xcrun swiftc \
ios/wrappers/CustomerIOReactNativeDeepLinkRequestStore.swift \
scripts/test_ios_deep_link_request_store.swift \
-o "$RUNNER_TEMP/test-ios-deep-link-request-store"
"$RUNNER_TEMP/test-ios-deep-link-request-store"

# Install CLI tools, Ruby, and Ruby dependencies for Fastlane
- name: Set IS_PRIMARY_APP
run: |
if [[ "${{ inputs.app_name }}" == "APN" ]]; then
echo "IS_PRIMARY_APP=true" >> $GITHUB_ENV
echo "PUSH_PROVIDER=apn" >> $GITHUB_ENV
echo "IS_PRIMARY_APP=true" >> "$GITHUB_ENV"
echo "PUSH_PROVIDER=apn" >> "$GITHUB_ENV"
else
echo "IS_PRIMARY_APP=false" >> $GITHUB_ENV
echo "PUSH_PROVIDER=fcm" >> $GITHUB_ENV
echo "IS_PRIMARY_APP=false" >> "$GITHUB_ENV"
echo "PUSH_PROVIDER=fcm" >> "$GITHUB_ENV"
fi

- name: Set Default Firebase Distribution Groups
Expand All @@ -109,7 +125,8 @@ jobs:
fi

# Export the groups as an environment variable
echo "firebase_distribution_groups=$(IFS=','; echo "${distribution_groups[*]}")" >> $GITHUB_ENV
groups=$(IFS=','; echo "${distribution_groups[*]}")
echo "firebase_distribution_groups=$groups" >> "$GITHUB_ENV"

- name: Install sd CLI for Android builds
if: ${{ inputs.platform == 'android' }}
Expand Down Expand Up @@ -147,9 +164,11 @@ jobs:
id: export-vars
run: |
echo "Exporting SDK and App Version..."
echo "sdk_version_name=${SDK_VERSION_NAME}" >> $GITHUB_OUTPUT
echo "app_version_name=${APP_VERSION_NAME}" >> $GITHUB_OUTPUT
echo "app_version_code=${APP_VERSION_CODE}" >> $GITHUB_OUTPUT
{
echo "sdk_version_name=${SDK_VERSION_NAME}"
echo "app_version_name=${APP_VERSION_NAME}"
echo "app_version_code=${APP_VERSION_CODE}"
} >> "$GITHUB_OUTPUT"
env:
SDK_VERSION_NAME: ${{ env.SDK_VERSION_NAME }}
APP_VERSION_NAME: ${{ env.APP_VERSION_NAME }}
Expand Down Expand Up @@ -180,10 +199,12 @@ jobs:
APP_VERSION_CODE: ${{ env.APP_VERSION_CODE }}

- name: Set Git Context Variables
env:
BRANCH_NAME_RAW: ${{ github.head_ref || github.ref_name }}
COMMIT_HASH_RAW: ${{ github.event_name == 'pull_request' && github.event.pull_request.head.sha || github.sha }}
run: |
echo "BRANCH_NAME=${{ github.head_ref || github.ref_name }}" >> $GITHUB_ENV
COMMIT_HASH="${{ github.event_name == 'pull_request' && github.event.pull_request.head.sha || github.sha }}"
echo "COMMIT_HASH=${COMMIT_HASH:0:7}" >> $GITHUB_ENV
echo "BRANCH_NAME=$BRANCH_NAME_RAW" >> "$GITHUB_ENV"
echo "COMMIT_HASH=${COMMIT_HASH_RAW:0:7}" >> "$GITHUB_ENV"

- name: Setup workspace credentials in React Native environment files
run: |
Expand Down Expand Up @@ -298,10 +319,13 @@ jobs:
uses: customerio/customerio-android/.github/actions/setup-android@main

- name: Setup ${{ inputs.platform_name }} environment for the ${{ inputs.platform }} sample app
# This action only selects the repository's supported Xcode version.
# Signing credentials are scoped to the distribution-only Fastlane step.
if: ${{ inputs.platform == 'ios' }}
uses: customerio/mobile-ci-tools/github-actions/ios/setup-ios/v1@main

- name: Build and upload ${{ inputs.platform_name }} ${{ inputs.app_name }} sample app via Fastlane
if: ${{ inputs.should_distribute }}
id: build_app
uses: maierj/fastlane-action@5a3b971aaa26776459bb26894d6c1a1a84a311a7 # v3.1.0
with:
Expand All @@ -314,8 +338,27 @@ jobs:
FIREBASE_APP_DISTRIBUTION_SERVICE_ACCOUNT_CREDS_B64: ${{ secrets.FIREBASE_APP_DISTRIBUTION_SERVICE_ACCOUNT_CREDS_B64 }}
continue-on-error: true

- name: Compile ${{ inputs.platform_name }} ${{ inputs.app_name }} sample app (verification only)
if: ${{ !inputs.should_distribute }}
id: verify_build
shell: bash
run: |
set -euo pipefail
if [[ "${{ inputs.platform }}" == 'android' ]]; then
./android/gradlew -p android :app:assembleRelease
else
xcodebuild \
-workspace ios/SampleApp.xcworkspace \
-scheme SampleApp \
-configuration Release \
-sdk iphonesimulator \
-destination 'generic/platform=iOS Simulator' \
CODE_SIGNING_ALLOWED=NO \
build
fi

- name: Send slack notification for ${{ inputs.platform_name }} ${{ inputs.app_name }} sample app builds
if: ${{ always() && env.IS_PRIMARY_APP == 'true' }}
if: ${{ always() && inputs.should_distribute && env.IS_PRIMARY_APP == 'true' }}
uses: customerio/mobile-ci-tools/github-actions/slack-notify-sample-app/v1@main
with:
build_status: ${{ steps.build_app.outcome }}
Expand All @@ -332,11 +375,18 @@ jobs:
slack_webhook_url: ${{ secrets.SLACK_WEBHOOK_URL }}

- name: Check build statuses and mark failure
if: ${{ always() }}
env:
SHOULD_DISTRIBUTE: ${{ inputs.should_distribute }}
DISTRIBUTION_OUTCOME: ${{ steps.build_app.outcome }}
VERIFICATION_OUTCOME: ${{ steps.verify_build.outcome }}
run: |
FAILED_BUILDS=()
[ "${{ steps.build_app.outcome }}" != "success" ] && FAILED_BUILDS+=("(${{ inputs.platform_name }})")

if [ ${#FAILED_BUILDS[@]} -ne 0 ]; then
echo "Build failed for: ${FAILED_BUILDS[*]}"
if [[ "$SHOULD_DISTRIBUTE" == 'true' ]]; then
outcome="$DISTRIBUTION_OUTCOME"
else
outcome="$VERIFICATION_OUTCOME"
fi
if [[ "$outcome" != 'success' ]]; then
echo "${{ inputs.platform_name }} build failed with outcome: $outcome"
exit 1
fi
Loading
Loading