Skip to content

Commit

Permalink
Android CircleCI to GitHub Actions reusable workflow conversion (#101)
Browse files Browse the repository at this point in the history
* Add license headers for iOS workflows

* Create Android build and test reusable workflow

* Apply testing config

* Add missing shell value

* Test removing dependency setup for validate code

* Update Android dependency action to handle no API level provided

* Reenable setup dependencies

* Propagate JAVA_HOME

* Add shell

* Rename id

* Fix output syntax

* Move java setup step

* Remove set java home step

* Disable deleting tools

* Move java setup back to dependency action

* Fix unit test command

* Cleanup unused code

* Apply prod configs

* Revert "Apply prod configs"

This reverts commit 39f5b23.

* Rename iOS integration test for consistency

* Rename integration test command for consistency

* Update job names for clarity

* Update job name

* Update iOS workflow job names for clarity

* Add log upload step

* Test adding timestamp to uploaded logs

* Update timestamp format for file name rules

* Update var name

* Update filename logic to apply filename to uploaded asset only

* Update filename logic

* Apply filename fallback logic and remove logcat prefix in asset name

* Update log file name

* Update log upload step to be non failure case for job

* Update codecov flag to default to false (must be opted in)

Apply prod config to workflows
Remove Android suffix from test job names
  • Loading branch information
timkimadobe authored Nov 22, 2024
1 parent 2b0d879 commit 1746edb
Show file tree
Hide file tree
Showing 8 changed files with 400 additions and 3 deletions.
86 changes: 86 additions & 0 deletions .github/actions/android-setup-dependencies-action/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
#
# Copyright 2024 Adobe. All rights reserved.
# This file is licensed to you under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License. You may obtain a copy
# of the License at http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software distributed under
# the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
# OF ANY KIND, either express or implied. See the License for the specific language
# governing permissions and limitations under the License.
#

name: Setup Dependencies (Android)
description: Checkout and install dependencies

inputs:
android-api-level:
description: 'The Android API level to use for testing.'
type: string
default: ''

runs:
using: "composite"
steps:
- name: Set up Java
uses: actions/setup-java@v4.2.2
with:
distribution: 'zulu'
java-version: 17
# This is to help reduce Android emulator boot up flakiness issues:
# See: https://github.com/ReactiveCircus/android-emulator-runner/issues/324#issuecomment-2009351180
- name: Delete unnecessary tools 🔧
uses: jlumbroso/free-disk-space@54081f138730dfa15788a46383842cd2f914a1be # v1.3.1
with:
android: false # Don't remove Android tools
tool-cache: false # Don't remove image tool cache - rm -rf "$AGENT_TOOLSDIRECTORY" (as this seems to remove the Java tooling set up in the previous step)
dotnet: true # rm -rf /usr/share/dotnet
haskell: true # rm -rf /opt/ghc...
swap-storage: true # rm -f /mnt/swapfile (4GiB)
docker-images: false # Takes 16s, enable if needed in the future
large-packages: false # includes google-cloud-sdk and it's slow
# The Android emulator requires Kernel-based Virtual Machine (KVM) access to run efficiently.
# This step ensures that the KVM is accessible with the proper permissions across all users.
- name: Enable KVM group permissions
run: |
echo 'KERNEL=="kvm", GROUP="kvm", MODE="0666", OPTIONS+="static_node=kvm"' | sudo tee /etc/udev/rules.d/99-kvm4all.rules
sudo udevadm control --reload-rules
sudo udevadm trigger --name-match=kvm
ls /dev/kvm
shell: bash

- name: Gradle cache
uses: gradle/actions/setup-gradle@v4.1.0

- name: AVD cache
if: ${{ inputs.android-api-level != '' }}
uses: actions/cache@v4.1.2
id: avd-cache
with:
path: |
~/.android/avd/*
~/.android/adb*
key: avd-${{ inputs.android-api-level }}

# Note that the AVD configurations must exactly match what's used in the test step, otherwise the cache will not be used.
- name: create AVD and generate snapshot for caching
if: ${{ steps.avd-cache.outputs.cache-hit != 'true' && inputs.android-api-level != '' }}
uses: reactivecircus/android-emulator-runner@f0d1ed2dcad93c7479e8b2f2226c83af54494915 # v2.32.0
with:
api-level: ${{ inputs.android-api-level }}
arch: x86_64
disk-size: 6000M
heap-size: 600M
force-avd-creation: false
emulator-options: -no-metrics -no-window -gpu swiftshader_indirect -noaudio -no-boot-anim -camera-back none
disable-animations: true
script: echo "Generated AVD snapshot for caching."

- name: Save AVD cache
if: ${{ steps.avd-cache.outputs.cache-hit != 'true' && inputs.android-api-level != '' }}
uses: actions/cache/save@v4.1.2
with:
path: |
~/.android/avd/*
~/.android/adb*
key: avd-${{ inputs.android-api-level }}
12 changes: 12 additions & 0 deletions .github/actions/ios-setup-dependencies-action/action.yml
Original file line number Diff line number Diff line change
@@ -1,3 +1,15 @@
#
# Copyright 2024 Adobe. All rights reserved.
# This file is licensed to you under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License. You may obtain a copy
# of the License at http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software distributed under
# the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
# OF ANY KIND, either express or implied. See the License for the specific language
# governing permissions and limitations under the License.
#

name: Setup Dependencies (iOS)
description: Checkout and install dependencies

Expand Down
98 changes: 98 additions & 0 deletions .github/workflows/android-build-and-test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
#
# Copyright 2024 Adobe. All rights reserved.
# This file is licensed to you under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License. You may obtain a copy
# of the License at http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software distributed under
# the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
# OF ANY KIND, either express or implied. See the License for the specific language
# governing permissions and limitations under the License.
#

name: Build and Test (Android)

on:
workflow_call:
inputs:
android-api-levels:
description: |
The Android API levels to use for testing. Must be formatted as a valid JSON array string.
Example: '[29, 30]'
- Notice the use of single quotes to wrap the JSON array string, and number format for values.
type: string
default: '[29]'
# Flags for which tests to run
run-test-unit:
type: boolean
default: false
run-test-functional:
type: boolean
default: false
run-test-integration:
type: boolean
default: false
run-build-app:
type: boolean
default: false
enable-codecov:
description: 'Enable Codecov for test coverage.'
type: boolean
default: false

jobs:
validate-code:
name: Validate Code
uses: adobe/aepsdk-commons/.github/workflows/android-validate-code.yml@gha-android-3.0.0

test-unit:
name: Unit Test
needs: validate-code
if: inputs.run-test-unit
uses: adobe/aepsdk-commons/.github/workflows/android-custom-command-build-and-test.yml@gha-android-3.0.0
with:
android-api-levels: ${{ inputs.android-api-levels }}
command: make unit-test-coverage
enable-codecov: ${{ inputs.enable-codecov }}
codecov-flag: android-unit-tests
secrets: inherit

test-functional:
name: Functional Test
needs: validate-code
if: inputs.run-test-functional
uses: adobe/aepsdk-commons/.github/workflows/android-custom-command-build-and-test.yml@gha-android-3.0.0
with:
android-api-levels: ${{ inputs.android-api-levels }}
command: make functional-test-coverage
enable-codecov: ${{ inputs.enable-codecov }}
codecov-flag: android-functional-tests
secrets: inherit

test-integration:
name: Integration Test
needs: validate-code
if: inputs.run-test-integration
uses: adobe/aepsdk-commons/.github/workflows/android-custom-command-build-and-test.yml@gha-android-3.0.0
with:
android-api-levels: ${{ inputs.android-api-levels }}
command: make integration-test-coverage
enable-codecov: ${{ inputs.enable-codecov }}
codecov-flag: android-integration-tests
secrets: inherit

build-app:
name: Build Test App
runs-on: ubuntu-latest
needs: validate-code
if: inputs.run-build-app

steps:
- name: Checkout Repository
uses: actions/checkout@v4.2.2

- name: Setup Dependencies
uses: adobe/aepsdk-commons/.github/actions/android-setup-dependencies-action@gha-android-3.0.0

- name: Assemble App
run: make assemble-app
129 changes: 129 additions & 0 deletions .github/workflows/android-custom-command-build-and-test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
#
# Copyright 2024 Adobe. All rights reserved.
# This file is licensed to you under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License. You may obtain a copy
# of the License at http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software distributed under
# the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
# OF ANY KIND, either express or implied. See the License for the specific language
# governing permissions and limitations under the License.
#

name: Custom Command Build and Test (Android)

on:
workflow_call:
inputs:
android-api-levels:
description: |
The Android API levels to use for testing. Must be formatted as a valid JSON array string.
Example: '[29, 30]'
- Notice the use of single quotes to wrap the JSON array string, and number format for values.
type: string
default: ''
command:
type: string
required: true
enable-codecov:
description: 'Enable Codecov for test coverage.'
type: boolean
default: true
codecov-flag:
description: 'The flag to pass to the codecov uploader.'
type: string
default: ''

jobs:
define-matrix:
name: Setup Configuration
runs-on: ubuntu-latest
outputs:
android-api-levels: ${{ steps.define-matrix.outputs.android-api-levels }}
is-default-android-api-levels: ${{ steps.define-matrix.outputs.is-default-android-api-levels }}
steps:
- name: Define Matrix
id: define-matrix
shell: bash
run: |
# Set default values
default_android_api_levels='[29]'
# Get inputs
android_api_levels='${{ inputs.android-api-levels }}'
# Check and set default values
if [ -z "$android_api_levels" ]; then
android_api_levels="$default_android_api_levels"
is_default_android_api_levels='true'
else
is_default_android_api_levels='false'
fi
# Set outputs
echo "android-api-levels=$android_api_levels" >> "$GITHUB_OUTPUT"
echo "is-default-android-api-levels=$is_default_android_api_levels" >> "$GITHUB_OUTPUT"
run-custom-command:
name: >
Test using Android API ${{ needs.define-matrix.outputs.is-default-android-api-levels != 'true' && matrix.api-level || '' }}
runs-on: ubuntu-latest
needs: define-matrix
strategy:
max-parallel: 1
matrix:
api-level: ${{ fromJson(needs.define-matrix.outputs.android-api-levels) }}

steps:
- name: Setup Dependencies
id: setup-dependencies
uses: adobe/aepsdk-commons/.github/actions/android-setup-dependencies-action@gha-android-3.0.0
with:
android-api-level: ${{ matrix.api-level }}

- name: Set JAVA_HOME
run: echo "JAVA_HOME=${{ steps.setup-dependencies.outputs.java-home }}" >> $GITHUB_ENV

- name: Checkout Repository
uses: actions/checkout@v4.2.2

- name: Set Log File Name
run: |
FILE_TIMESTAMP=$(date -u +"%Y-%m-%d_%H-%M-%S")
COMMAND_NAME=$(echo "${{ inputs.command }}" | awk '{print $2 ? $2 : $1}' | sed 's/[^a-zA-Z0-9_-]//g') # Extract the second word of the command and filter out invalid filename chars
echo "LOG_FILE_NAME=logs-${COMMAND_NAME}_API-${{ matrix.api-level }}_${FILE_TIMESTAMP}Z.log" >> $GITHUB_ENV
# Logcat logging from: https://github.com/ReactiveCircus/android-emulator-runner/issues/9#issuecomment-867909354
- name: Run tests
uses: reactivecircus/android-emulator-runner@f0d1ed2dcad93c7479e8b2f2226c83af54494915 # v2.32.0
with:
api-level: ${{ matrix.api-level }}
arch: x86_64
disk-size: 6000M
heap-size: 600M
force-avd-creation: false
emulator-options: -no-snapshot-save -no-metrics -no-window -gpu swiftshader_indirect -noaudio -no-boot-anim -camera-back none
disable-animations: true
script: |
mkdir -p logs # Ensure the 'logs' directory exists
adb logcat -c # Clear logs
touch logs/emulator.log # Create log file
chmod 777 logs/emulator.log # Allow writing to log file
adb logcat >> logs/emulator.log & # Pipe all logcat messages into log file as a background process
${{ inputs.command }}
- name: Upload Logcat Logs
if: always()
continue-on-error: true
uses: actions/upload-artifact@v4.4.0
with:
name: ${{ env.LOG_FILE_NAME }}
path: logs/emulator.log

- name: Upload Code Coverage
if: ${{ inputs.enable-codecov }}
uses: codecov/codecov-action@b9fd7d16f6d7d1b5d2bec1a2887e65ceed900238 # v4.6.0
with:
token: ${{ secrets.CODECOV_TOKEN }}
flags: ${{ inputs.codecov-flag }}
verbose: true
35 changes: 35 additions & 0 deletions .github/workflows/android-validate-code.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
#
# Copyright 2024 Adobe. All rights reserved.
# This file is licensed to you under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License. You may obtain a copy
# of the License at http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software distributed under
# the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
# OF ANY KIND, either express or implied. See the License for the specific language
# governing permissions and limitations under the License.
#

name: Validate Code (Android)

on:
workflow_call:

jobs:
validate-code:
name: Validate Code
runs-on: ubuntu-latest

steps:
- name: Checkout Repository
uses: actions/checkout@v4.2.2

- name: Setup Dependencies
id: setup-dependencies
uses: adobe/aepsdk-commons/.github/actions/android-setup-dependencies-action@gha-android-3.0.0

- name: Check Format
run: make checkformat

- name: Lint Source Code
run: make lint
Loading

0 comments on commit 1746edb

Please sign in to comment.