publish-cli #1
Workflow file for this run
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: publish-cli | |
| on: | |
| push: | |
| branches: | |
| - main | |
| tags: | |
| - '**' | |
| pull_request: | |
| # Manual trigger: dispatch on a tag ref (--ref <tag>) to (re)run the release | |
| # for that tag. Needed because event-triggered runs don't fire on this fork | |
| # until workflows are enabled from the Actions tab by an org admin. | |
| workflow_dispatch: | |
| env: | |
| GRADLE_OPTS: "-Dorg.gradle.jvmargs=-Xmx6g -Dorg.gradle.daemon=false -Dkotlin.incremental=false" | |
| permissions: | |
| contents: write | |
| jobs: | |
| build: | |
| runs-on: ubuntu-latest | |
| concurrency: | |
| group: ${{ github.workflow }}-build-${{ github.ref }} | |
| cancel-in-progress: true | |
| steps: | |
| - uses: actions/checkout@v4 | |
| with: | |
| fetch-depth: 0 | |
| fetch-tags: true | |
| - uses: actions/setup-java@v4 | |
| with: | |
| distribution: 'jetbrains' | |
| java-version: '17' | |
| java-package: 'jdk' # optional (jdk, jre, jdk+jcef, jre+jcef, jdk+ft, or jre+ft) - defaults to jdk | |
| env: | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| - name: Setup Gradle | |
| uses: gradle/actions/setup-gradle@v4 | |
| with: | |
| cache-encryption-key: ${{ secrets.GRADLE_ENCRYPTION_KEY }} | |
| - name: build | |
| id: build | |
| run: | | |
| ./gradlew arbigent-cli:assemble --stacktrace | |
| - uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4 | |
| if: ${{ always() }} | |
| with: | |
| name: cli-artifact | |
| path: | | |
| arbigent-cli/build/distributions/* | |
| retention-days: 120 | |
| - name: Release | |
| uses: softprops/action-gh-release@v2 | |
| if: startsWith(github.ref, 'refs/tags/') | |
| with: | |
| files: | | |
| arbigent-cli/build/distributions/* | |
| - name: Extract version | |
| id: extract-version | |
| run: | | |
| printf "::set-output name=%s::%s\n" tag-name "${GITHUB_REF#refs/tags/}" | |
| - name: Update formula on tag | |
| if: (github.event_name == 'push' || github.event_name == 'workflow_dispatch') && startsWith(github.ref, 'refs/tags/') | |
| uses: "mislav/bump-homebrew-formula-action@v2" | |
| with: | |
| download-url: https://github.com/Entertech/arbigent/releases/download/${{ steps.extract-version.outputs.tag-name }}/arbigent-${{ steps.extract-version.outputs.tag-name }}.tar.gz | |
| formula-name: arbigent | |
| homebrew-tap: Entertech/homebrew-tap | |
| env: | |
| # The repo secret is named COMMITER_TOKEN (sic, single T) | |
| COMMITTER_TOKEN: ${{ secrets.COMMITER_TOKEN }} | |
| cli-e2e-android: | |
| runs-on: ubuntu-latest | |
| concurrency: | |
| group: ${{ github.workflow }}-cli-e2e-android-${{ github.ref }}-${{ matrix.shardIndex }}-${{ matrix.shardTotal }} | |
| cancel-in-progress: true | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| shardIndex: [ 1, 2 ] | |
| shardTotal: [ 2 ] | |
| steps: | |
| - name: Delete unnecessary tools 🔧 | |
| uses: jlumbroso/free-disk-space@v1.3.1 | |
| with: | |
| android: false # Don't remove Android tools | |
| tool-cache: true # Remove image tool cache - rm -rf "$AGENT_TOOLSDIRECTORY" | |
| 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 | |
| - name: Enable KVM group perms | |
| 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 | |
| - uses: actions/checkout@v4 | |
| with: | |
| fetch-depth: 0 | |
| fetch-tags: true | |
| - uses: actions/setup-java@v4 | |
| with: | |
| distribution: 'jetbrains' | |
| java-version: '17' | |
| java-package: 'jdk' # optional (jdk, jre, jdk+jcef, jre+jcef, jdk+ft, or jre+ft) - defaults to jdk | |
| env: | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| - name: Setup Gradle | |
| uses: gradle/actions/setup-gradle@v4 | |
| with: | |
| cache-encryption-key: ${{ secrets.GRADLE_ENCRYPTION_KEY }} | |
| - name: build | |
| id: build | |
| run: | | |
| ./gradlew arbigent-cli:installDist --stacktrace | |
| - name: Cache arbigent | |
| uses: actions/cache@v4 | |
| with: | |
| # Caution: If we use the same cache key without GitHub SHA, the cache will not be updated. | |
| key: arbigent-${{ matrix.shardIndex }}-${{ matrix.shardTotal }}-${{ github.sha }} | |
| restore-keys: arbigent-${{ matrix.shardIndex }}-${{ matrix.shardTotal }}- | |
| path: arbigent-cache | |
| - uses: actions/setup-node@v4 | |
| with: | |
| node-version: 22 | |
| - name: CLI E2E test | |
| uses: reactivecircus/android-emulator-runner@v2 | |
| env: | |
| OPENAI_API_KEY: ${{ secrets.OPEN_ROUTER_API_KEY }} | |
| with: | |
| api-level: 34 | |
| arch: x86_64 | |
| disable-animations: true | |
| disk-size: 6000M | |
| heap-size: 600M | |
| script: | | |
| set -eu | |
| arbigent-cli/build/install/arbigent/bin/arbigent run --os=android --project-file=sample-test/src/main/resources/projects/e2e-test-android.yaml --ai-type=openai --openai-endpoint=https://openrouter.ai/api/v1/ --openai-model-name=google/gemma-4-31b-it --shard=${{ matrix.shardIndex }}/${{ matrix.shardTotal }} --variables "search_term=Bluetooth,app_package=com.android.camera2" | |
| if [ "${{ matrix.shardIndex }}" = "1" ]; then arbigent-cli/build/install/arbigent/bin/arbigent run --os=android --project-file=sample-test/src/main/resources/projects/e2e-test-android-responses.yaml --ai-type=openai --openai-endpoint=https://openrouter.ai/api/v1/ --openai-model-name=openai/gpt-5.4-mini; fi | |
| - name: Check API key leakage | |
| run: | | |
| if grep -R --quiet "${{ secrets.OPEN_ROUTER_API_KEY }}" arbigent-result/; then | |
| echo "::error::API key leaked in results!" | |
| exit 1 | |
| fi | |
| - uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4 | |
| if: ${{ always() }} | |
| with: | |
| name: cli-report-android-${{ matrix.shardIndex }}-${{ matrix.shardTotal }} | |
| path: | | |
| arbigent-result/* | |
| retention-days: 120 | |
| cli-e2e-ios: | |
| # Use macOS 14 as it has Xcode 15.4 pre-installed at /Applications/Xcode_15.4.app | |
| # macOS 15 (macos-latest) does not include Xcode 15.4 by default | |
| runs-on: macos-14 | |
| concurrency: | |
| group: ${{ github.workflow }}-cli-e2e-ios-${{ github.ref }} | |
| cancel-in-progress: true | |
| steps: | |
| - uses: actions/checkout@v4 | |
| with: | |
| fetch-depth: 0 | |
| fetch-tags: true | |
| - uses: actions/setup-java@v4 | |
| with: | |
| distribution: 'jetbrains' | |
| java-version: '17' | |
| java-package: 'jdk' # optional (jdk, jre, jdk+jcef, jre+jcef, jdk+ft, or jre+ft) - defaults to jdk | |
| env: | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| - name: Setup Gradle | |
| uses: gradle/actions/setup-gradle@v4 | |
| with: | |
| cache-encryption-key: ${{ secrets.GRADLE_ENCRYPTION_KEY }} | |
| - name: build | |
| id: build | |
| run: | | |
| ./gradlew arbigent-cli:installDist --stacktrace | |
| - name: Install Xcode | |
| run: | | |
| # Select Xcode 15.4 | |
| sudo xcode-select -s /Applications/Xcode_15.4.app | |
| # Check Xcode version | |
| xcodebuild -version | |
| - name: Install applesimutils | |
| run: brew tap wix/brew && brew install applesimutils | |
| - name: Start iOS Simulator with Custom Timeout | |
| run: | | |
| # List available devices | |
| xcrun simctl list devices | |
| # Shutdown all simulators to ensure a clean state | |
| echo "Shutting down all simulators..." | |
| xcrun simctl shutdown all | |
| # Boot the iPhone 15 Pro simulator | |
| echo "Booting iPhone 15 Pro simulator..." | |
| xcrun simctl boot "iPhone 15 Pro" | |
| # Start bootstatus in background (-b blocks until boot complete) | |
| echo "Waiting for simulator to finish booting..." | |
| xcrun simctl bootstatus "iPhone 15 Pro" -b & | |
| BOOT_PID=$! | |
| # Set maximum timeout in seconds | |
| MAX_TIMEOUT=300 | |
| elapsed=0 | |
| # Loop until bootstatus process finishes or timeout is reached | |
| while kill -0 $BOOT_PID 2>/dev/null; do | |
| sleep 1 | |
| elapsed=$((elapsed+1)) | |
| echo "Elapsed time: $elapsed seconds" | |
| if [ $elapsed -ge $MAX_TIMEOUT ]; then | |
| echo "Error: Simulator failed to boot within the timeout period." | |
| kill $BOOT_PID | |
| exit 1 | |
| fi | |
| done | |
| echo "Simulator booted successfully." | |
| - name: CLI E2E test for iOS | |
| env: | |
| OPENAI_API_KEY: ${{ secrets.OPEN_ROUTER_API_KEY }} | |
| run: | | |
| arbigent-cli/build/install/arbigent/bin/arbigent run --os=ios --project-file=sample-test/src/main/resources/projects/e2e-test-ios.yaml --ai-type=openai --openai-endpoint=https://openrouter.ai/api/v1/ --openai-model-name=google/gemma-4-31b-it | |
| - name: Check API key leakage | |
| run: | | |
| if grep -R --quiet "${{ secrets.OPEN_ROUTER_API_KEY }}" arbigent-result/; then | |
| echo "::error::API key leaked in results!" | |
| exit 1 | |
| fi | |
| - uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4 | |
| if: ${{ always() }} | |
| with: | |
| name: cli-ios-report | |
| path: | | |
| arbigent-result/* | |
| retention-days: 120 |