### GitHub Actions Upload and Output Example
Source: https://github.com/mobile-dev-inc/action-maestro-cloud/blob/main/_autodocs/configuration.md
This example demonstrates how to use the action to upload an app and then access its output variables in subsequent steps.
```yaml
- id: upload
uses: mobile-dev-inc/action-maestro-cloud@v3
with:
api-key: ${{ secrets.MAESTRO_CLOUD_API_KEY }}
project-id: ${{ env.PROJECT_ID }}
app-file: app.apk
- name: Check Results
run: |
echo "Binary ID: ${{ steps.upload.outputs.MAESTRO_CLOUD_APP_BINARY_ID }}"
echo "Console: ${{ steps.upload.outputs.MAESTRO_CLOUD_CONSOLE_URL }}"
echo "Status: ${{ steps.upload.outputs.MAESTRO_CLOUD_UPLOAD_STATUS }}"
echo "Results: ${{ steps.upload.outputs.MAESTRO_CLOUD_FLOW_RESULTS }}"
```
--------------------------------
### Multiline Environment Variable Example
Source: https://github.com/mobile-dev-inc/action-maestro-cloud/blob/main/_autodocs/types.md
Provides an example of how to format the multiline 'env' input for the GitHub Action. It shows a typical structure with multiple environment variables defined on separate lines.
```text
USERNAME=alice
PASSWORD=secret123
API_ENDPOINT=https://api.example.com
```
--------------------------------
### Postprocess Execution Examples
Source: https://github.com/mobile-dev-inc/action-maestro-cloud/blob/main/_autodocs/api-reference/postprocess.md
Illustrates how to run the postprocess script in different modes. The synchronous mode passes an exit code, while the asynchronous mode does not. Examples also show behavior with a missing JUnit file.
```bash
# Synchronous mode (exit code passed):
node dist/postprocess.js /tmp/junit.xml 0
# Sets: MAESTRO_CLOUD_FLOW_RESULTS='[{"name":"login","status":"SUCCESS","errors":[]}]'
# MAESTRO_CLOUD_UPLOAD_STATUS='SUCCESS'
# Async mode (no exit code):
node dist/postprocess.js /tmp/junit.xml
# Sets: MAESTRO_CLOUD_FLOW_RESULTS='[]'
# (MAESTRO_CLOUD_UPLOAD_STATUS not set)
# Missing file:
node dist/postprocess.js /nonexistent/junit.xml 0
# Sets: MAESTRO_CLOUD_FLOW_RESULTS='[]'
# MAESTRO_CLOUD_UPLOAD_STATUS='SUCCESS' (exit 0)
```
--------------------------------
### Usage Pattern: Uploading and then Using App Binary ID
Source: https://github.com/mobile-dev-inc/action-maestro-cloud/blob/main/_autodocs/configuration.md
Example demonstrating uploading an app in one step and referencing its ID in a subsequent step.
```yaml
- id: upload
uses: mobile-dev-inc/action-maestro-cloud@v3
with:
api-key: ${{ secrets.MAESTRO_CLOUD_API_KEY }}
project-id: ${{ env.PROJECT_ID }}
app-file: app.zip
- uses: mobile-dev-inc/action-maestro-cloud@v3
with:
api-key: ${{ secrets.MAESTRO_CLOUD_API_KEY }}
project-id: ${{ env.PROJECT_ID }}
app-binary-id: ${{ steps.upload.outputs.MAESTRO_CLOUD_APP_BINARY_ID }}
```
--------------------------------
### FlowResult Example
Source: https://github.com/mobile-dev-inc/action-maestro-cloud/blob/main/_autodocs/api-reference/postprocess.md
An example demonstrating how to create a FlowResult object, indicating a flow named 'login-flow' that encountered an error.
```typescript
const flow: FlowResult = {
name: 'login-flow',
status: 'ERROR',
errors: ['Element "LoginButton" not found after 10 seconds']
}
```
--------------------------------
### Incorrect File Path Example
Source: https://github.com/mobile-dev-inc/action-maestro-cloud/blob/main/_autodocs/README.md
Illustrates an incorrect configuration where the 'app-file' path is specified incorrectly, potentially leading to a 'File Not Found' error.
```yaml
# Wrong
app-file: 'app.apk'
```
--------------------------------
### Environment Variable Layering Example
Source: https://github.com/mobile-dev-inc/action-maestro-cloud/blob/main/_autodocs/architecture.md
Demonstrates how environment variables are exported and potentially cleared across job steps using $GITHUB_ENV to prevent stale data leakage.
```text
Job Step 1:
exportVariable('MDEV_APP_BINARY_ID', 'app_xyz') → $GITHUB_ENV
$GITHUB_ENV accumulates:
MDEV_APP_BINARY_ID=app_xyz
Job Step 2 (same action, different invocation):
exportVariable('MDEV_APP_FILE', '/path/to/app.apk')
exportVariable('MDEV_APP_BINARY_ID', '') ← Clear previous step's value
→ $GITHUB_ENV overwrites with empty
$GITHUB_ENV now contains:
MDEV_APP_BINARY_ID= ← Empty (cleared)
MDEV_APP_FILE=/path/to/app.apk
```
--------------------------------
### Derive Upload Status Example
Source: https://github.com/mobile-dev-inc/action-maestro-cloud/blob/main/_autodocs/types.md
Demonstrates the usage of the `deriveUploadStatus` function, showing how it processes an array of `FlowResult` objects and an exit code to determine the overall upload status. This example results in an 'ERROR' status due to a flow failure.
```typescript
const status: UploadStatus = deriveUploadStatus(
[
{ name: 'auth-flow', status: 'SUCCESS', errors: [] },
{ name: 'payment-flow', status: 'ERROR', errors: ['Payment gateway timeout'] }
],
1
);
// Result: 'ERROR'
```
--------------------------------
### App Input Validation for Mobile Tests
Source: https://github.com/mobile-dev-inc/action-maestro-cloud/blob/main/_autodocs/errors.md
For non-web OS, provide exactly one of 'app-file' or 'app-binary-id'. This example shows valid configurations.
```yaml
# Case 1: app-file only
app-file: 'app.apk'
app-binary-id: '' # Not provided
# Case 2: app-binary-id only
app-file: '' # Not provided
app-binary-id: 'app_xyz'
```
--------------------------------
### parseJunit Example Usage
Source: https://github.com/mobile-dev-inc/action-maestro-cloud/blob/main/_autodocs/api-reference/postprocess.md
Demonstrates how to use the parseJunit function with a sample JUnit XML string and shows the expected array of FlowResult objects.
```typescript
const xml = `
Element "PaymentButton" not found
`
const results = parseJunit(xml);
// Returns:
// [
// { name: 'login', status: 'SUCCESS', errors: [] },
// { name: 'checkout', status: 'ERROR', errors: ['Element "PaymentButton" not found'] }
// ]
```
--------------------------------
### App Input Validation for Web Tests
Source: https://github.com/mobile-dev-inc/action-maestro-cloud/blob/main/_autodocs/errors.md
For web tests, omit both 'app-file' and 'app-binary-id'. This example shows a valid web configuration.
```yaml
device-os: 'web'
# app-file and app-binary-id omitted
```
--------------------------------
### Example Upload Status Output
Source: https://github.com/mobile-dev-inc/action-maestro-cloud/blob/main/README.md
Illustrates possible values for the MAESTRO_CLOUD_UPLOAD_STATUS output variable.
```plaintext
PENDING
PREPARING
INSTALLING
RUNNING
SUCCESS
ERROR
CANCELED
WARNING
STOPPED
```
--------------------------------
### Example Environment Variables After Execution
Source: https://github.com/mobile-dev-inc/action-maestro-cloud/blob/main/_autodocs/api-reference/prelude.md
Illustrates the environment variables exported by the action after its main execution, specifically for an app-file upload scenario. This helps in understanding the output format and available parameters.
```typescript
// This is called automatically by the action; no direct invocation needed.
// Example environment after main() completes (for app-file upload):
// MDEV_API_KEY=rb_xyz
// MDEV_PROJECT_ID=proj_abc
// MDEV_BRANCH=feature/foo
// MDEV_NAME=Add feature X
// MDEV_APP_FILE=/work/app.apk
// MDEV_APP_BINARY_ID=
// MDEV_MAPPING_FILE=
// MDEV_DEVICE_OS=android-33
// ... (other MDEV_* variables)
```
--------------------------------
### Basic GitHub Actions Workflow Setup
Source: https://github.com/mobile-dev-inc/action-maestro-cloud/blob/main/README.md
Add this snippet to your GitHub Actions workflow file to run Flows on Maestro Cloud. Ensure you replace the placeholder project ID and app file path with your actual values. The API key should be stored as a secret.
```yaml
- uses: mobile-dev-inc/action-maestro-cloud@v3.0.1
with:
api-key: ${{ secrets.MAESTRO_CLOUD_API_KEY }}
project-id: 'proj_01example0example1example2' # replace this with your actual project id
app-file:
```
--------------------------------
### Test Prelude Setup
Source: https://github.com/mobile-dev-inc/action-maestro-cloud/blob/main/_autodocs/testing.md
Resets mocks and clears environment variables before each test to ensure isolation. Cleans up INPUT_* environment variables after each test.
```typescript
beforeEach(() => {
;(github as any).context = JSON.parse(JSON.stringify(baseContext))
exportedVars = {}
jest.spyOn(core, 'exportVariable').mockImplementation((k, v) => {
exportedVars[k] = String(v)
})
jest.spyOn(core, 'setFailed').mockImplementation((m) => {
failures.push(typeof m === 'string' ? m : m.message)
})
})
afterEach(() => {
jest.restoreAllMocks()
for (const k of Object.keys(process.env)) {
if (k.startsWith('INPUT_')) delete process.env[k]
}
})
```
--------------------------------
### Specify iOS Device Model and OS Version
Source: https://github.com/mobile-dev-inc/action-maestro-cloud/blob/main/README.md
Configure the action to run tests on a specific iOS device model and OS version. Use 'iPhone-11' for device model and 'iOS-18-2' for OS version as examples.
```yaml
- uses: mobile-dev-inc/action-maestro-cloud@v3.0.1
with:
api-key: ${{ secrets.MAESTRO_CLOUD_API_KEY }}
project-id: 'proj_01example0example1example2'
app-file: app.zip
device-model: iPhone-11
device-os: iOS-18-2
```
--------------------------------
### Run BATS Integration Tests
Source: https://github.com/mobile-dev-inc/action-maestro-cloud/blob/main/_autodocs/testing.md
Execute BATS integration tests for the bash script. Requires BATS to be installed globally.
```bash
BATS_LIB_PATH=$(npm root -g) bats __tests__/run-cloud.bats
```
--------------------------------
### Specify Android Device Model and OS Version
Source: https://github.com/mobile-dev-inc/action-maestro-cloud/blob/main/README.md
Configure the action to run tests on a specific Android device model and OS version. Use 'pixel_6' for device model and 'android-33' for OS version as examples.
```yaml
- uses: mobile-dev-inc/action-maestro-cloud@v3.0.1
with:
api-key: ${{ secrets.MAESTRO_CLOUD_API_KEY }}
project-id: 'proj_01example0example1example2'
app-file: app.apk
device-model: pixel_6
device-os: android-33
```
--------------------------------
### FlowResult Example Usage
Source: https://github.com/mobile-dev-inc/action-maestro-cloud/blob/main/_autodocs/types.md
Illustrates how to create a `FlowResult` object, typically used to represent a failed flow. The example shows a flow named 'login-flow' with an 'ERROR' status and a specific error message.
```typescript
const result: FlowResult = {
name: 'login-flow',
status: 'ERROR',
errors: ['Button "Sign In" not found after 10 seconds']
}
```
--------------------------------
### Parsing Flow Results with jq
Source: https://github.com/mobile-dev-inc/action-maestro-cloud/blob/main/_autodocs/configuration.md
Example of parsing the JSON output of `MAESTRO_CLOUD_FLOW_RESULTS` using `jq` to filter for errors.
```yaml
- run: |
RESULTS='${{ steps.upload.outputs.MAESTRO_CLOUD_FLOW_RESULTS }}'
# Parse with jq
echo "$RESULTS" | jq '.[] | select(.status=="ERROR") | .name'
```
--------------------------------
### Example Flow Results Output
Source: https://github.com/mobile-dev-inc/action-maestro-cloud/blob/main/README.md
Shows the structure of the MAESTRO_CLOUD_FLOW_RESULTS output variable, which is an array of objects detailing flow execution status and errors.
```json
[
{ "name": "my-first-flow", "status": "SUCCESS", "errors": [] },
{ "name": "my-second-flow", "status": "SUCCESS", "errors": [] },
{ "name": "my-cancelled-flow", "status": "CANCELED", "errors": [] }
]
```
--------------------------------
### Derive Upload Status Examples
Source: https://github.com/mobile-dev-inc/action-maestro-cloud/blob/main/_autodocs/api-reference/postprocess.md
Demonstrates how the `deriveUploadStatus` function determines the overall upload status based on an array of flow results and an exit code. It covers various scenarios including success, errors, stopped flows, and handling of empty flow arrays.
```typescript
const flows1: FlowResult[] = [
{ name: 'a', status: 'SUCCESS', errors: [] },
{ name: 'b', status: 'SUCCESS', errors: [] }
];
deriveUploadStatus(flows1, 0); // Returns: 'SUCCESS'
const flows2: FlowResult[] = [
{ name: 'a', status: 'SUCCESS', errors: [] },
{ name: 'b', status: 'ERROR', errors: ['Element not found'] }
];
deriveUploadStatus(flows2, 1); // Returns: 'ERROR'
const flows3: FlowResult[] = [
{ name: 'a', status: 'SUCCESS', errors: [] },
{ name: 'b', status: 'STOPPED', errors: [] }
];
deriveUploadStatus(flows3, 1); // Returns: 'STOPPED'
// Empty flows: trust exit code
deriveUploadStatus([], 0); // Returns: 'SUCCESS'
deriveUploadStatus([], 1); // Returns: 'ERROR'
```
--------------------------------
### Build and Upload App Binary
Source: https://github.com/mobile-dev-inc/action-maestro-cloud/blob/main/_autodocs/configuration.md
This snippet demonstrates a two-step process: first building the app, then uploading it. The upload step can be configured for different platforms.
```yaml
- id: build
run: |
# Build app and upload
./build.sh
- id: upload-android
uses: mobile-dev-inc/action-maestro-cloud@v3.0.1
with:
api-key: ${{ secrets.MAESTRO_CLOUD_API_KEY }}
project-id: 'proj_android'
app-file: app-android.apk
- id: upload-ios
uses: mobile-dev-inc/action-maestro-cloud@v3.0.1
with:
api-key: ${{ secrets.MAESTRO_CLOUD_API_KEY }}
project-id: 'proj_ios'
app-binary-id: ${{ steps.upload-android.outputs.MAESTRO_CLOUD_APP_BINARY_ID }}
```
--------------------------------
### main
Source: https://github.com/mobile-dev-inc/action-maestro-cloud/blob/main/_autodocs/api-reference/prelude.md
The main entry point for the prelude step. It reads and validates GitHub Actions inputs, resolves file globs, and exports environment variables for downstream steps.
```APIDOC
## main
### Description
Main entry point for the prelude step. Reads all GitHub Actions inputs, validates them, resolves file globs, and exports environment variables via `core.exportVariable` for consumption by downstream steps.
### Method
async function
### Parameters
None. Reads from GitHub Actions inputs and context.
### Return Type
`Promise` - Does not return a value; side effects via `core.exportVariable`.
### Example
```typescript
// This function is typically called automatically by the action runner.
// Direct invocation example:
await main();
```
```
--------------------------------
### Run Release Command
Source: https://github.com/mobile-dev-inc/action-maestro-cloud/blob/main/RELEASING.md
Execute this command to build and push artifacts for a new release. Replace `` with the desired semantic version (e.g., 1.2.3).
```bash
npm run release
```
--------------------------------
### Run All Tests
Source: https://github.com/mobile-dev-inc/action-maestro-cloud/blob/main/_autodocs/testing.md
Execute all integration and unit tests using npm.
```bash
npm test
```
--------------------------------
### iOS Configuration
Source: https://github.com/mobile-dev-inc/action-maestro-cloud/blob/main/README.md
Configure the action for iOS builds, specifying the .app file path.
```yaml
- uses: mobile-dev-inc/action-maestro-cloud@v3.0.1
with:
api-key: ${{ secrets.MAESTRO_CLOUD_API_KEY }}
project-id: 'proj_01example0example1example2'
app-file: .app
mapping-file: .app.dSYM
```
--------------------------------
### Minimal Action Configuration
Source: https://github.com/mobile-dev-inc/action-maestro-cloud/blob/main/_autodocs/configuration.md
The most basic configuration for the action, requiring only API key, project ID, and the app file.
```yaml
- uses: mobile-dev-inc/action-maestro-cloud@v3.0.1
with:
api-key: ${{ secrets.MAESTRO_CLOUD_API_KEY }}
project-id: 'proj_01example0example1example2'
app-file: app.apk
```
--------------------------------
### Run Web Tests
Source: https://github.com/mobile-dev-inc/action-maestro-cloud/blob/main/README.md
Execute web tests by setting 'device-os' to 'web'. The 'app-file' input is not required for web tests.
```yaml
- uses: mobile-dev-inc/action-maestro-cloud@v3.0.1
with:
api-key: ${{ secrets.MAESTRO_CLOUD_API_KEY }}
project-id: 'proj_01example0example1example2'
device-os: web
```
--------------------------------
### Optional Input: Workspace
Source: https://github.com/mobile-dev-inc/action-maestro-cloud/blob/main/_autodocs/configuration.md
Directory containing Maestro flow files (.yaml or .yml). Defaults to '.maestro' if not specified.
```yaml
workspace: 'myFlows/'
```
--------------------------------
### Android Configuration
Source: https://github.com/mobile-dev-inc/action-maestro-cloud/blob/main/README.md
Configure the action for Android builds, specifying the APK file path.
```yaml
- uses: mobile-dev-inc/action-maestro-cloud@v3.0.1
with:
api-key: ${{ secrets.MAESTRO_CLOUD_API_KEY }}
project-id: 'proj_01example0example1example2'
app-file: app/build/outputs/apk/debug/app-debug.apk
```
--------------------------------
### Upload App Binary and Use App Binary ID
Source: https://github.com/mobile-dev-inc/action-maestro-cloud/blob/main/README.md
Uploads an app binary and then uses its ID in a subsequent step. Ensure the 'upload' step completes successfully before referencing its outputs.
```yaml
- id: upload
uses: mobile-dev-inc/action-maestro-cloud@v3.0.1
with:
api-key: ${{ secrets.MAESTRO_CLOUD_API_KEY }}
project-id: 'proj_01example0example1example2'
app-file: app.zip
- uses: mobile-dev-inc/action-maestro-cloud@v3.0.1
with:
api-key: ${{ secrets.MAESTRO_CLOUD_API_KEY }}
project-id: 'proj_01example0example1example2'
app-binary-id: ${{ steps.upload.outputs.MAESTRO_CLOUD_APP_BINARY_ID }}
```
--------------------------------
### Specify App Build Output Path
Source: https://github.com/mobile-dev-inc/action-maestro-cloud/blob/main/_autodocs/README.md
Use 'app-file' to specify the path to your application's build output. Supports exact paths or glob patterns.
```yaml
app-file: 'app/build/outputs/apk/debug/app-debug.apk'
```
```yaml
app-file: '**/build/outputs/apk/debug/*.apk'
```
--------------------------------
### Trigger Workflow on Issue Comment with Custom Branch
Source: https://github.com/mobile-dev-inc/action-maestro-cloud/blob/main/_autodocs/configuration.md
This example shows how to trigger a workflow on an issue comment and use the comment to specify a custom branch for testing. It retrieves the branch name using the GitHub CLI.
```yaml
on:
issue_comment:
types: [created]
jobs:
test:
if: contains(github.event.comment.body, '/test')
runs-on: ubuntu-latest
steps:
- name: Get PR branch
id: pr
env:
PR_NUMBER: ${{ github.event.issue.number }}
GH_TOKEN: ${{ github.token }}
run: |
HEAD_REF=$(gh pr view "$PR_NUMBER" --json headRefName --jq '.headRefName')
echo "branch=$HEAD_REF" >> $GITHUB_OUTPUT
- uses: mobile-dev-inc/action-maestro-cloud@v3.0.1
with:
api-key: ${{ secrets.MAESTRO_CLOUD_API_KEY }}
project-id: 'proj_01example0example1example2'
app-file: app.zip
branch: ${{ steps.pr.outputs.branch }}
```
--------------------------------
### Advanced Configuration for App Upload
Source: https://github.com/mobile-dev-inc/action-maestro-cloud/blob/main/_autodocs/configuration.md
Use this snippet for detailed app upload configurations, including device specifics, workspace, tags, and environment variables.
```yaml
- id: upload
uses: mobile-dev-inc/action-maestro-cloud@v3.0.1
with:
api-key: ${{ secrets.MAESTRO_CLOUD_API_KEY }}
project-id: 'proj_01example0example1example2'
app-file: app.apk
device-os: 'android-33'
device-model: 'pixel_6'
device-locale: 'de_DE'
workspace: 'flows/'
include-tags: 'smoke'
exclude-tags: 'flaky,wip'
env: |
USERNAME=${{ secrets.TEST_USER }}
PASSWORD=${{ secrets.TEST_PASS }}
ENVIRONMENT=staging
timeout: '90'
```
--------------------------------
### Minimal Action Maestro Cloud Configuration
Source: https://github.com/mobile-dev-inc/action-maestro-cloud/blob/main/_autodocs/README.md
Basic configuration for the Action Maestro Cloud. Requires API key, project ID, and the application file path.
```yaml
- uses: mobile-dev-inc/action-maestro-cloud@v3
with:
api-key: ${{ secrets.MAESTRO_CLOUD_API_KEY }}
project-id: 'proj_01example'
app-file: app.apk
```
--------------------------------
### Arithmetic Expansion for Condition Testing in Bash
Source: https://github.com/mobile-dev-inc/action-maestro-cloud/blob/main/_autodocs/api-reference/shell-script.md
While the example shows a common conditional test `[ -z "$VAR" ]` for checking if a variable is empty, arithmetic expansion itself is typically used for mathematical operations like `(( expression ))`.
```bash
[ -z "$VAR" ]
```
--------------------------------
### Maestro Cloud CLI Command Structure
Source: https://github.com/mobile-dev-inc/action-maestro-cloud/blob/main/_autodocs/architecture.md
This bash script demonstrates how the maestro cloud CLI command is constructed using environment variables and optional flags. It is used to upload applications and run tests.
```bash
maestro cloud \
--apiKey "$MDEV_API_KEY" \
--project-id "$MDEV_PROJECT_ID" \
[optional flags] \
"${env_args[@]}" \
"${format_args[@]}" \
--flows "$MDEV_WORKSPACE"
```
--------------------------------
### Conditional Input: App File (APK/IPA/Bundle)
Source: https://github.com/mobile-dev-inc/action-maestro-cloud/blob/main/_autodocs/configuration.md
Path to the application binary or a glob pattern. Used when `app-binary-id` is not provided.
```yaml
app-file: app/build/outputs/apk/debug/app-debug.apk
```
```yaml
# or glob pattern:
app-file: app/build/outputs/apk/**/*.apk
```
--------------------------------
### iOS Configuration with dSYM Mapping File
Source: https://github.com/mobile-dev-inc/action-maestro-cloud/blob/main/_autodocs/configuration.md
Configure the action for an iOS app, including the path to the dSYM file for symbolication.
```yaml
- uses: mobile-dev-inc/action-maestro-cloud@v3.0.1
with:
api-key: ${{ secrets.MAESTRO_CLOUD_API_KEY }}
project-id: 'proj_01example0example1example2'
app-file: MyApp.app
mapping-file: MyApp.app.dSYM
```
--------------------------------
### Build Process Script
Source: https://github.com/mobile-dev-inc/action-maestro-cloud/blob/main/_autodocs/architecture.md
The build script used to compile TypeScript files and bundle them with dependencies using @vercel/ncc.
```bash
npm run build
# Compiles prelude.ts and postprocess.ts to dist/prelude.js and dist/postprocess.js
# Uses @vercel/ncc for bundling with dependencies
```
--------------------------------
### Async Mode App Upload
Source: https://github.com/mobile-dev-inc/action-maestro-cloud/blob/main/_autodocs/configuration.md
Configure the action to run in async mode for non-blocking uploads. This is useful when you don't need immediate feedback on the upload status.
```yaml
- uses: mobile-dev-inc/action-maestro-cloud@v3.0.1
with:
api-key: ${{ secrets.MAESTRO_CLOUD_API_KEY }}
project-id: 'proj_01example0example1example2'
app-file: app.apk
async: 'true'
```
--------------------------------
### Create Temporary Files and Set Cleanup Trap
Source: https://github.com/mobile-dev-inc/action-maestro-cloud/blob/main/_autodocs/api-reference/shell-script.md
This snippet creates temporary files for JUnit XML output and standard CLI output capture. It also sets up a trap to ensure these temporary files are removed upon script exit, whether successful or due to an error.
```bash
JUNIT_FILE=$(mktemp "${TMPDIR:-/tmp}/maestro-junit.XXXXXX") || \
{ echo "::error::failed to create temp junit file"; exit 1; }
OUTPUT_FILE=$(mktemp) || \
{ echo "::error::failed to create temp file for CLI output"; exit 1; }
trap 'rm -f "$OUTPUT_FILE" "$JUNIT_FILE"' EXIT
```
--------------------------------
### Enable Asynchronous Flow Execution
Source: https://github.com/mobile-dev-inc/action-maestro-cloud/blob/main/_autodocs/configuration.md
Set to 'true' to return immediately without waiting for flow results. Output variables like results and status will not be available.
```yaml
async: 'true'
```
--------------------------------
### Simulate GitHub Actions Inputs
Source: https://github.com/mobile-dev-inc/action-maestro-cloud/blob/main/_autodocs/testing.md
Sets environment variables prefixed with INPUT_ to simulate GitHub Actions inputs for testing. Clears existing INPUT_* variables before setting new ones.
```typescript
const setInputs = (inputs: Record) => {
for (const k of Object.keys(process.env)) {
if (k.startsWith('INPUT_')) delete process.env[k]
}
for (const [k, v] of Object.entries(inputs)) {
process.env[`INPUT_${k.replace(/ /g, '_').toUpperCase()}`] = v
}
}
setInputs({ 'api-key': 'k', 'project-id': 'p', 'app-file': 'a.apk' })
```
--------------------------------
### Correctly Set Environment Variables
Source: https://github.com/mobile-dev-inc/action-maestro-cloud/blob/main/_autodocs/README.md
Environment variables must be set with a key-value pair using '='. Avoid setting them with only a key.
```yaml
# Wrong (missing =)
env: |
USERNAME
# Correct
env: |
USERNAME=alice
PASSWORD=secret
```
--------------------------------
### Specify Target Device Model
Source: https://github.com/mobile-dev-inc/action-maestro-cloud/blob/main/_autodocs/configuration.md
Define the specific device model for running flows. Use 'maestro list-devices' to find supported models.
```yaml
# iOS
device-model: 'iPhone-11'
device-model: 'iPhone-14-Pro'
# Android
device-model: 'pixel_6'
device-model: 'pixel_7'
```
--------------------------------
### Custom Device and Environment Variables
Source: https://github.com/mobile-dev-inc/action-maestro-cloud/blob/main/_autodocs/README.md
Configures the Action Maestro Cloud to target a specific device OS, model, and locale, and sets custom environment variables for the test run.
```yaml
- uses: mobile-dev-inc/action-maestro-cloud@v3
with:
api-key: ${{ secrets.MAESTRO_CLOUD_API_KEY }}
project-id: 'proj_01example'
app-file: app.apk
device-os: 'android-33'
device-model: 'pixel_6'
device-locale: 'de_DE'
env: |
USERNAME=${{ secrets.TEST_USER }}
PASSWORD=${{ secrets.TEST_PASS }}
```
--------------------------------
### Access Action Output Variables
Source: https://github.com/mobile-dev-inc/action-maestro-cloud/blob/main/README.md
Demonstrates how to access and print various output variables set by the action, such as console URL, flow results, upload status, and app binary ID. The 'if: always()' condition ensures these commands run regardless of previous step failures.
```yaml
- id: upload
uses: mobile-dev-inc/action-maestro-cloud@v3.0.1
with:
api-key: ${{ secrets.MAESTRO_CLOUD_API_KEY }}
project-id: 'proj_01example0example1example2'
app-file:
# ... any other parameters
- name: Access Outputs
if: always()
run: |
echo "Console URL: ${{ steps.upload.outputs.MAESTRO_CLOUD_CONSOLE_URL }}"
echo "Flow Results: ${{ steps.upload.outputs.MAESTRO_CLOUD_FLOW_RESULTS }}"
echo "Upload Status: ${{ steps.upload.outputs.MAESTRO_CLOUD_UPLOAD_STATUS }}"
echo "App Binary ID: ${{ steps.upload.outputs.MAESTRO_CLOUD_APP_BINARY_ID }}"
```
--------------------------------
### Postprocess Main Function Signature
Source: https://github.com/mobile-dev-inc/action-maestro-cloud/blob/main/_autodocs/api-reference/postprocess.md
The main entry point for the postprocess step. It reads a JUnit XML file, parses flow results, derives the upload status, and sets GitHub Actions outputs. It reads parameters from command-line arguments.
```typescript
async function main(): Promise
```
--------------------------------
### Release Process Script
Source: https://github.com/mobile-dev-inc/action-maestro-cloud/blob/main/_autodocs/architecture.md
The script responsible for tagging, pushing, and creating GitHub releases.
```bash
./_release.sh
# Tag, push, and create GitHub release
```
--------------------------------
### Async Upload Configuration
Source: https://github.com/mobile-dev-inc/action-maestro-cloud/blob/main/_autodocs/README.md
Configures the Action Maestro Cloud for an asynchronous upload. The action returns immediately after initiating the upload.
```yaml
- uses: mobile-dev-inc/action-maestro-cloud@v3
with:
api-key: ${{ secrets.MAESTRO_CLOUD_API_KEY }}
project-id: 'proj_01example'
app-file: app.apk
async: 'true'
```
--------------------------------
### Validate App Input (File or Binary ID)
Source: https://github.com/mobile-dev-inc/action-maestro-cloud/blob/main/_autodocs/README.md
Provide either 'app-file' or 'app-binary-id', but not both. This ensures the action knows which application artifact to use.
```yaml
# Wrong (both provided)
app-file: 'app.apk'
app-binary-id: 'app_xyz'
# Correct (app-file only)
app-file: 'app.apk'
# Correct (app-binary-id only)
app-binary-id: 'app_xyz'
```
--------------------------------
### Maestro CLI Output Processing
Source: https://github.com/mobile-dev-inc/action-maestro-cloud/blob/main/_autodocs/architecture.md
Illustrates the flow of data and processing steps from the Maestro CLI's standard output to GitHub Actions outputs.
```text
maestro CLI stdout
↓
run-cloud.sh: Parse & capture
↓
- Extract binary ID (regex: "App binary id: \S+")
- Extract console URL (regex: "https://app.maestro.dev/\S+")
- Run postprocess.js
↓
postprocess.ts: parseJunit(junit_xml)
↓
Flow results + upload status
↓
core.setOutput(key, value)
↓
$GITHUB_OUTPUT (GitHub Actions' output persistence)
↓
Downstream steps: ${{ steps.id.outputs.KEY }}
```
--------------------------------
### Extract App Binary ID and Console URL
Source: https://github.com/mobile-dev-inc/action-maestro-cloud/blob/main/_autodocs/api-reference/shell-script.md
Parses the cleaned CLI output to extract the 'App binary id' and the Maestro console URL using `grep`, `awk`, and `head`. These patterns are designed to match the specific output format of the Maestro CLI.
```bash
APP_BINARY_ID=$(echo "$CLEANED" | grep -oE "App binary id: \S+" | awk '{print $NF}' | head -n 1)
CONSOLE_URL=$(echo "$CLEANED" | grep -oE "https://app\.maestro\.dev/\S+" | head -n 1)
```
--------------------------------
### Optional Input: Name
Source: https://github.com/mobile-dev-inc/action-maestro-cloud/blob/main/_autodocs/configuration.md
A friendly name for the upload. If omitted, it's auto-derived from the PR title, commit message, or commit SHA.
```yaml
name: 'My Custom Run Name'
```
--------------------------------
### Inspect Action Outputs in GitHub Actions
Source: https://github.com/mobile-dev-inc/action-maestro-cloud/blob/main/_autodocs/errors.md
Log the output variables produced by a GitHub Actions step. This is crucial for understanding the results of the action and for passing data to subsequent steps.
```yaml
- run: |
echo "Binary ID: ${{ steps.upload.outputs.MAESTRO_CLOUD_APP_BINARY_ID }}"
echo "Console URL: ${{ steps.upload.outputs.MAESTRO_CLOUD_CONSOLE_URL }}"
echo "Status: ${{ steps.upload.outputs.MAESTRO_CLOUD_UPLOAD_STATUS }}"
echo "Results: ${{ steps.upload.outputs.MAESTRO_CLOUD_FLOW_RESULTS }}"
```
--------------------------------
### Build Maestro Cloud CLI Command Array
Source: https://github.com/mobile-dev-inc/action-maestro-cloud/blob/main/_autodocs/api-reference/shell-script.md
Constructs a bash array representing the maestro cloud command. It uses conditional expansions for optional flags and handles format arguments based on the MDEV_ASYNC variable.
```bash
format_args=()
if [ -z "$MDEV_ASYNC" ]; then
format_args=(--format junit --output "$JUNIT_FILE")
fi
CLOUD_COMMAND=(
maestro cloud
--apiKey "$MDEV_API_KEY"
--project-id "$MDEV_PROJECT_ID"
${MDEV_API_URL:+--api-url "$MDEV_API_URL"}
${MDEV_NAME:+--name "$MDEV_NAME"}
${MDEV_BRANCH:+--branch "$MDEV_BRANCH"}
${MDEV_COMMIT_SHA:+--commit-sha "$MDEV_COMMIT_SHA"}
${MDEV_REPO_OWNER:+--repoOwner "$MDEV_REPO_OWNER"}
${MDEV_REPO_NAME:+--repoName "$MDEV_REPO_NAME"}
${MDEV_PR_ID:+--pullRequestId "$MDEV_PR_ID"}
${MDEV_APP_FILE:+--app-file "$MDEV_APP_FILE"}
${MDEV_APP_BINARY_ID:+--app-binary-id "$MDEV_APP_BINARY_ID"}
${MDEV_MAPPING_FILE:+--mapping "$MDEV_MAPPING_FILE"}
${MDEV_DEVICE_OS:+--device-os "$MDEV_DEVICE_OS"}
${MDEV_DEVICE_LOCALE:+--device-locale "$MDEV_DEVICE_LOCALE"}
${MDEV_DEVICE_MODEL:+--device-model "$MDEV_DEVICE_MODEL"}
${MDEV_INCLUDE_TAGS:+--include-tags "$MDEV_INCLUDE_TAGS"}
${MDEV_EXCLUDE_TAGS:+--exclude-tags "$MDEV_EXCLUDE_TAGS"}
${MDEV_TIMEOUT:+--timeout "$MDEV_TIMEOUT"}
${MDEV_ASYNC:+--async}
${MDEV_ANDROID_API_LEVEL:+--android-api-level "$MDEV_ANDROID_API_LEVEL"}
${MDEV_IOS_VERSION:+--ios-version "$MDEV_IOS_VERSION"}
"${format_args[@]+${format_args[@]}}"
"${env_args[@]+${env_args[@]}}"
--flows "${MDEV_WORKSPACE:-.maestro}"
)
```
```bash
maestro cloud \
--apiKey "rb_xyz" \
--project-id "proj_abc" \
--name "My Upload" \
--branch "feature/foo" \
--device-os "android-33" \
--format junit --output "/tmp/junit.XXXXXX" \
-e "USERNAME=alice" \
-e "PASSWORD=secret" \
--flows ".maestro"
```
--------------------------------
### Android Upload with ProGuard Mapping
Source: https://github.com/mobile-dev-inc/action-maestro-cloud/blob/main/_autodocs/README.md
Configuration for uploading an Android application with ProGuard mapping files. This is essential for deobfuscating stack traces from release builds.
```yaml
- uses: mobile-dev-inc/action-maestro-cloud@v3
with:
api-key: ${{ secrets.MAESTRO_CLOUD_API_KEY }}
project-id: 'proj_01example'
app-file: app/build/outputs/apk/release/app-release.apk
mapping-file: app/build/outputs/mapping/release/mapping.txt
```
--------------------------------
### Generate Coverage Report
Source: https://github.com/mobile-dev-inc/action-maestro-cloud/blob/main/_autodocs/testing.md
Generate a test coverage report.
```bash
npm run test:coverage
```
--------------------------------
### GitHub Actions Primitive String Inputs
Source: https://github.com/mobile-dev-inc/action-maestro-cloud/blob/main/_autodocs/types.md
Lists the primitive string inputs accepted by the GitHub Action. These cover essential configuration like API keys, project IDs, and optional parameters for customizing the upload and execution.
```typescript
{
'api-key': string // Required. API authentication key.
'project-id': string // Required. Maestro Cloud project identifier.
'api-url': string // Optional. Custom API endpoint URL.
'name': string // Optional. Display name for the upload.
'branch': string // Optional. Git branch name (overrides detection).
'app-file': string // Optional (required if no app-binary-id). App file path or glob.
'app-binary-id': string // Optional (required if no app-file). Pre-uploaded binary ID.
'mapping-file': string // Optional. ProGuard mapping or dSYM file path.
'workspace': string // Optional. Maestro flows directory (default: .maestro).
'device-os': string // Optional. Target OS version (e.g., android-33, iOS-18-2, web).
'device-model': string // Optional. Target device model (e.g., pixel_6, iPhone-11).
'device-locale': string // Optional. Device locale (e.g., en_US, de_DE).
'include-tags': string // Optional. Comma-separated tags to include.
'exclude-tags': string // Optional. Comma-separated tags to exclude.
'timeout': string // Optional. Minutes to wait (numeric string).
'async': string // Optional. Boolean as string: 'true' or 'false'.
'maestro-cli-version': string // Optional. Specific CLI version pin.
'android-api-level': string // Deprecated. Use device-os instead.
'ios-version': string // Deprecated. Use device-os instead.
}
```
--------------------------------
### Handle Temp File Creation Failures
Source: https://github.com/mobile-dev-inc/action-maestro-cloud/blob/main/_autodocs/api-reference/shell-script.md
Writes an error message to standard output using GitHub Actions error directive and exits with status 1 if temporary file creation fails.
```bash
{ echo "::error::failed to create temp junit file"; exit 1; }
```
--------------------------------
### Optional Input: Mapping File (Android/iOS)
Source: https://github.com/mobile-dev-inc/action-maestro-cloud/blob/main/_autodocs/configuration.md
Path to ProGuard mapping file (Android) or dSYM archive (iOS) for symbol deobfuscation. Supports glob patterns.
```yaml
# Android
mapping-file: app/build/outputs/mapping/release/mapping.txt
```
```yaml
# iOS
mapping-file: MyApp.app.dSYM
```
--------------------------------
### Input to Internal Variables Data Flow
Source: https://github.com/mobile-dev-inc/action-maestro-cloud/blob/main/_autodocs/architecture.md
Illustrates the data flow from GitHub Actions inputs to internal environment variables used by the action. This process involves input retrieval, validation, and environment variable export.
```text
GitHub Actions inputs (action.yml)
↓
prelude.ts: core.getInput(key)
↓
Validation & transformation
↓
core.exportVariable(MDEV_*, value)
↓
$GITHUB_ENV (GitHub Actions' environment persistence)
↓
run-cloud.sh: Read ${MDEV_*} variables
```
--------------------------------
### Set GitHub Actions Outputs
Source: https://github.com/mobile-dev-inc/action-maestro-cloud/blob/main/_autodocs/api-reference/shell-script.md
Conditionally writes environment variables to the GITHUB_OUTPUT file in the format KEY=VALUE. This is used to pass information to subsequent steps in a GitHub Actions workflow.
```bash
[ -n "$APP_BINARY_ID" ] && echo "MAESTRO_CLOUD_APP_BINARY_ID=$APP_BINARY_ID" >> "$GITHUB_OUTPUT"
[ -n "$CONSOLE_URL" ] && echo "MAESTRO_CLOUD_CONSOLE_URL=$CONSOLE_URL" >> "$GITHUB_OUTPUT"
```
--------------------------------
### Run Action in Asynchronous Mode
Source: https://github.com/mobile-dev-inc/action-maestro-cloud/blob/main/README.md
Configure the action to run asynchronously, meaning it won't wait for the upload to complete. This is useful for faster workflow execution when immediate feedback on upload status is not critical.
```yaml
- uses: mobile-dev-inc/action-maestro-cloud@v3.0.1
with:
api-key: ${{ secrets.MAESTRO_CLOUD_API_KEY }}
project-id: 'proj_01example0example1example2'
app-file: app.zip
async: true
```
--------------------------------
### Verify Action Inputs in GitHub Actions
Source: https://github.com/mobile-dev-inc/action-maestro-cloud/blob/main/_autodocs/errors.md
Log the values of inputs passed to a GitHub Actions workflow step. This is a common debugging technique to ensure the correct data is being used.
```yaml
- run: |
echo "api-key: ${{ inputs.api-key }}"
echo "project-id: ${{ inputs.project-id }}"
echo "app-file: ${{ inputs.app-file }}"
```
--------------------------------
### iOS Upload with dSYM Mapping
Source: https://github.com/mobile-dev-inc/action-maestro-cloud/blob/main/_autodocs/README.md
Configuration for uploading an iOS application with dSYM files. This allows for symbolication of crash reports.
```yaml
- uses: mobile-dev-inc/action-maestro-cloud@v3
with:
api-key: ${{ secrets.MAESTRO_CLOUD_API_KEY }}
project-id: 'proj_01example'
app-file: MyApp.app
mapping-file: MyApp.app.dSYM
```
--------------------------------
### Specify Device Locale
Source: https://github.com/mobile-dev-inc/action-maestro-cloud/blob/main/_autodocs/configuration.md
Set the locale for the target device. The format is ISO-639-1 (lowercase) plus ISO-3166-1 (uppercase), separated by an underscore.
```yaml
device-locale: 'en_US'
device-locale: 'de_DE'
device-locale: 'fr_FR'
```
--------------------------------
### Configure Device Locale
Source: https://github.com/mobile-dev-inc/action-maestro-cloud/blob/main/README.md
Sets the device locale for test execution. The locale format is a combination of ISO-639-1 and ISO-3166-1 codes (e.g., 'de_DE').
```yaml
- uses: mobile-dev-inc/action-maestro-cloud@v3.0.1
with:
api-key: ${{ secrets.MAESTRO_CLOUD_API_KEY }}
project-id: 'proj_01example0example1example2'
app-file: app.zip
device-locale: de_DE
```
--------------------------------
### Pass Environment Variables to Upload
Source: https://github.com/mobile-dev-inc/action-maestro-cloud/blob/main/README.md
Include environment variables as a multiline string in the 'env' argument. This allows you to pass custom configurations or secrets to your test environment.
```yaml
- uses: mobile-dev-inc/action-maestro-cloud@v3.0.1
with:
api-key: ${{ secrets.MAESTRO_CLOUD_API_KEY }}
project-id: 'proj_01example0example1example2'
app-file: app.zip
env: |
USERNAME=
PASSWORD=
```
--------------------------------
### Enable Debug Logging in GitHub Actions
Source: https://github.com/mobile-dev-inc/action-maestro-cloud/blob/main/_autodocs/errors.md
Set the `ACTIONS_STEP_DEBUG` environment variable to `true` to enable verbose logging within GitHub Actions. This will log all inputs and environment variables for debugging purposes.
```yaml
env:
ACTIONS_STEP_DEBUG: true
```
--------------------------------
### Watch Mode for Tests
Source: https://github.com/mobile-dev-inc/action-maestro-cloud/blob/main/_autodocs/testing.md
Continuously re-run tests in response to file changes.
```bash
npm run test:watch
```
--------------------------------
### Maestro CLI Version Pinning
Source: https://github.com/mobile-dev-inc/action-maestro-cloud/blob/main/_autodocs/configuration.md
Configure a specific version of the Maestro CLI to be used by the action. Defaults to the latest version if not specified.
```yaml
maestro-cli-version: '1.37.0'
```
--------------------------------
### Optional Input: Branch
Source: https://github.com/mobile-dev-inc/action-maestro-cloud/blob/main/_autodocs/configuration.md
Git branch name for upload metadata. Auto-detected from GitHub context if omitted. Useful for specific event triggers.
```yaml
branch: 'feature/my-feature'
```
--------------------------------
### Conditional Input: App Binary ID
Source: https://github.com/mobile-dev-inc/action-maestro-cloud/blob/main/_autodocs/configuration.md
ID of a previously uploaded binary. Use when the app is already uploaded and `app-file` is not provided.
```yaml
app-binary-id: ${{ steps.upload.outputs.MAESTRO_CLOUD_APP_BINARY_ID }}
```
--------------------------------
### Execute Maestro CLI and Capture Output/Exit Code
Source: https://github.com/mobile-dev-inc/action-maestro-cloud/blob/main/_autodocs/api-reference/shell-script.md
Executes the constructed Maestro CLI command and pipes its standard output to `tee` for simultaneous display and file capture. It specifically captures the exit code of the CLI command, not `tee`.
```bash
"${CLOUD_COMMAND[@]}" | tee "$OUTPUT_FILE"
EXIT_CODE=${PIPESTATUS[0]}
```
--------------------------------
### Fixing App File Glob Pattern
Source: https://github.com/mobile-dev-inc/action-maestro-cloud/blob/main/_autodocs/errors.md
Correct the 'app-file' path or glob pattern if it resolves to zero matching files. Ensure the file exists in the working directory.
```yaml
# Correct path
app-file: 'app/build/outputs/apk/debug/app-debug.apk'
# Or use glob
app-file: '**/app-debug.apk'
```
--------------------------------
### Defensive XML Parsing for JUnit Testcases
Source: https://github.com/mobile-dev-inc/action-maestro-cloud/blob/main/_autodocs/testing.md
Demonstrates how the `parseJunit` function defensively ignores testcases that are missing required attributes like 'name' or 'status'. This allows for partial parsing of malformed JUnit XML files.
```typescript
it('ignores testcases missing name or status', () => {
const xml = `
`
expect(parseJunit(xml)).toEqual([
{ name: 'z', status: 'SUCCESS', errors: [] },
])
})
```
--------------------------------
### Deprecated iOS Version Configuration
Source: https://github.com/mobile-dev-inc/action-maestro-cloud/blob/main/_autodocs/configuration.md
This snippet shows the deprecated `ios-version` configuration. It is recommended to use `device-os` instead.
```yaml
ios-version: '18' # ⚠ Deprecated
```
--------------------------------
### Conditional Step Execution Based on Success or Failure
Source: https://github.com/mobile-dev-inc/action-maestro-cloud/blob/main/_autodocs/errors.md
Implement conditional logic in GitHub Actions to execute specific steps based on whether a previous step succeeded or failed. This is useful for reporting or cleanup.
```yaml
- id: upload
uses: mobile-dev-inc/action-maestro-cloud@v3
with:
api-key: ${{ secrets.MAESTRO_CLOUD_API_KEY }}
project-id: 'proj_xyz'
app-file: 'app.apk'
- name: Report Success
if: success()
run: |
echo "Upload status: ${{ steps.upload.outputs.MAESTRO_CLOUD_UPLOAD_STATUS }}"
- name: Report Failure
if: failure()
run: |
echo "Upload failed; check action logs"
```