All skills
callstackincubator avatar

/github-actions

@405a888 official

GitHub Actions workflow patterns for React Native iOS simulator and Android emulator cloud builds with downloadable artifacts. Use when setting up CI build pipelines or downloading GitHub Actions artifacts via gh CLI and GitHub API.

Use this Skill: https://skilld.dev/gh/callstackincubator/agent-skills/github-actions

This session only. Nothing lands on disk.

referencesgha-android-composite-action.md

≈1.3k tokens on demand. Your agent reads this file only when SKILL.md points to it.

Skill: Android Emulator Composite Action (RN CLI)

Composite action template for building React Native Android emulator APKs in GitHub Actions and uploading the resulting artifact.

Quick Config

  1. Create .github/actions/github-actions/android-build/action.yml.
  2. Copy the template below.
  3. Set variant (for emulator flows, use Debug by default).
  4. Use action outputs (artifact-name, artifact-id, artifact-url) in downstream jobs.

When to Use

  • Need cloud Android emulator build artifacts for testing.
  • Need configurable debug-style builds from one action.
  • Need reliable artifact retrieval through gh and REST API.

Prerequisites

  • Linux runner with JDK 17.
  • React Native dependencies installed.
  • Android SDK and Gradle wrapper available in the repository.

Template (.github/actions/github-actions/android-build/action.yml)

name: React Native Android Emulator Build
description: Build React Native Android emulator APK in GitHub Actions and upload artifact

inputs:
  working-directory:
    description: Project root
    required: false
    default: "."
  variant:
    description: Build variant (Debug by default for emulator flows)
    required: false
    default: Debug
  artifact-prefix:
    description: Prefix for artifact naming
    required: false
    default: rn-android-emulator
  custom-identifier:
    description: Optional stable identifier (PR number, channel, etc.)
    required: false
  artifact-retention-days:
    description: GitHub artifact retention
    required: false
    default: "7"

outputs:
  artifact-name:
    description: Uploaded artifact name
    value: ${{ steps.names.outputs.artifact_name }}
  artifact-id:
    description: Uploaded artifact id
    value: ${{ steps.upload.outputs.artifact-id }}
  artifact-url:
    description: Uploaded artifact URL
    value: ${{ steps.upload.outputs.artifact-url }}

runs:
  using: composite
  steps:
    - name: Resolve Android project settings
      id: resolve
      shell: bash
      working-directory: ${{ inputs.working-directory }}
      run: |
        set -euo pipefail

        CONFIG_JSON="$(npx react-native config)"
        ANDROID_SOURCE_DIR="$(printf '%s' "$CONFIG_JSON" | node -e "const fs=require('fs');const j=JSON.parse(fs.readFileSync(0,'utf8'));process.stdout.write(j.project?.android?.sourceDir || 'android')")"
        APP_NAME="$(printf '%s' "$CONFIG_JSON" | node -e "const fs=require('fs');const j=JSON.parse(fs.readFileSync(0,'utf8'));process.stdout.write(j.project?.android?.appName || 'app')")"

        IDENTIFIER="${{ inputs.custom-identifier }}"
        if [[ -z "$IDENTIFIER" ]]; then
          if [[ "${{ github.event_name }}" == "pull_request" ]]; then
            IDENTIFIER="pr-${{ github.event.pull_request.number }}"
          else
            IDENTIFIER="${GITHUB_SHA::7}"
          fi
        fi

        echo "android_source_dir=$ANDROID_SOURCE_DIR" >> "$GITHUB_OUTPUT"
        echo "app_name=$APP_NAME" >> "$GITHUB_OUTPUT"
        echo "identifier=$IDENTIFIER" >> "$GITHUB_OUTPUT"

    - name: Build Android APK
      id: build
      shell: bash
      working-directory: ${{ inputs.working-directory }}
      run: |
        set -euo pipefail

        VARIANT="${{ inputs.variant }}"
        VARIANT_LOWER="$(echo "$VARIANT" | tr '[:upper:]' '[:lower:]')"
        GRADLE_TASK="assemble${VARIANT}"

        (
          cd "${{ steps.resolve.outputs.android_source_dir }}"
          ./gradlew ":${{ steps.resolve.outputs.app_name }}:${GRADLE_TASK}"
        )

        OUTPUT_ROOT="${{ steps.resolve.outputs.android_source_dir }}/${{ steps.resolve.outputs.app_name }}/build/outputs/apk"
        SEARCH_DIR="$OUTPUT_ROOT"
        if [[ -d "$OUTPUT_ROOT/$VARIANT_LOWER" ]]; then
          SEARCH_DIR="$OUTPUT_ROOT/$VARIANT_LOWER"
        fi

        APK_PATH="$(find "$SEARCH_DIR" -type f -name '*.apk' ! -name '*androidTest*' | sort | head -n1 || true)"
        if [[ -z "$APK_PATH" ]]; then
          APK_PATH="$(find "$OUTPUT_ROOT" -type f -name '*.apk' ! -name '*androidTest*' | sort | head -n1 || true)"
        fi

        if [[ -z "$APK_PATH" ]]; then
          echo "No Android APK found"
          exit 1
        fi

        echo "apk_path=$APK_PATH" >> "$GITHUB_OUTPUT"

    - name: Build artifact name
      id: names
      shell: bash
      run: |
        set -euo pipefail

        VARIANT="$(echo "${{ inputs.variant }}" | tr '[:upper:]' '[:lower:]')"
        NAME="${{ inputs.artifact-prefix }}-${VARIANT}-${{ steps.resolve.outputs.identifier }}"
        echo "artifact_name=$NAME" >> "$GITHUB_OUTPUT"

    - name: Upload artifact
      id: upload
      uses: actions/upload-artifact@v4
      with:
        name: ${{ steps.names.outputs.artifact_name }}
        path: ${{ steps.build.outputs.apk_path }}
        if-no-files-found: error
        retention-days: ${{ inputs.artifact-retention-days }}

Common Pitfalls

  • Lowercase variant values causing wrong Gradle task names.
  • Missing JDK setup in caller workflow.
  • Hardcoding module name to app when react-native config reports a custom appName.

Related Skills

Source: SKILL.md on GitHub

1 alert16d5 checks · Risk SAFE
  • Gen Agent Trust Hub16d

    This skill provides reusable GitHub Actions templates and documentation for building React Native applications in CI and managing build artifacts. It uses official GitHub actions and established React Native CLI patterns.

  • Socket16d

    1 alert: gptAnomaly

  • Snyk16d

    Risk: LOW · No issues

  • Runlayer7mo

    3/5 files flagged

  • ZeroLeaks5mo

    Score: 93/100 · 2 sections analyzed

Signed by skilld at 405a888. This ties the file your Agent reads to that commit on GitHub. It does not review the instructions.

Last checked against GitHub 2 weeks ago.

Activeupdated 2 months ago
  • github-actions
  • ci
  • react-native
  • ios
  • android
  • artifacts
  • gh-cli
  • mobile-builds

README badge

README badge for callstackincubator/agent-skills/github-actions

Defines reusable GitHub Actions composite actions to build React Native iOS simulator and Android emulator artifacts in cloud CI, then download them via gh CLI or GitHub API. Use this skill when setting up mobile build pipelines that need retrievable simulator and emulator installables from PR or manual dispatch runs.

Generated from the current SKILL.md.

Does this skill support both iOS and Android builds?
Yes. The skill includes separate composite actions for iOS simulator `.app.tar.gz` builds and Android emulator `.apk` builds, both wired into a single workflow.
How do I download artifacts after a workflow run?
The skill provides `gh run download` commands and REST API examples. You can retrieve artifacts by `artifact-id` using either the GitHub CLI or direct HTTP calls to the GitHub API.
What does this skill actually build and upload?
It builds React Native apps for CI environments — iOS simulator apps as `.app.tar.gz` archives and Android emulator apps as `.apk` files — then publishes them as downloadable GitHub Actions artifacts.
Do I need to set up iOS and Android locally first?
The skill assumes you have a React Native project with iOS and Android build configurations already in place. It provides the GitHub Actions patterns to run those builds in the cloud and capture the outputs.

Generated from the current SKILL.md. These answers refresh after source changes.