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
54 changes: 38 additions & 16 deletions actions/run-ios-comment-session/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,18 @@ inputs:
description: Original issue comment body. Flags such as no-cache-sim, latest-device, and quality=tiny are honored.
required: false
default: simdeck run ios
command_comment_id:
description: GitHub issue comment id that triggered the session. When set, the action reacts to this comment immediately.
required: false
default: ""
command_comment_author:
description: GitHub username to mention when the URL is ready.
required: false
default: ""
command_reaction:
description: Reaction to add to the triggering comment. Use one of +1, -1, laugh, confused, heart, hooray, rocket, eyes.
required: false
default: eyes
pr_sha:
description: Optional pull request head SHA. When omitted, the action resolves it through the GitHub API.
required: false
Expand Down Expand Up @@ -82,6 +94,9 @@ runs:
PR_NUMBER_VALUE: ${{ inputs.pr_number }}
PR_SHA_INPUT_VALUE: ${{ inputs.pr_sha }}
SIMDECK_COMMENT_BODY_VALUE: ${{ inputs.command }}
COMMAND_COMMENT_ID_VALUE: ${{ inputs.command_comment_id }}
COMMAND_COMMENT_AUTHOR_VALUE: ${{ inputs.command_comment_author }}
COMMAND_REACTION_VALUE: ${{ inputs.command_reaction }}
SIMDECK_BUNDLE_ID_VALUE: ${{ inputs.bundle_id }}
SIMDECK_PORT_VALUE: ${{ inputs.simdeck_port }}
SIMDECK_PACKAGE_VALUE: ${{ inputs.simdeck_package }}
Expand Down Expand Up @@ -114,6 +129,9 @@ runs:
write_env "PR_NUMBER" "${PR_NUMBER_VALUE}"
write_env "PR_SHA_INPUT" "${PR_SHA_INPUT_VALUE}"
write_env "SIMDECK_COMMENT_BODY" "${SIMDECK_COMMENT_BODY_VALUE}"
write_env "COMMAND_COMMENT_ID" "${COMMAND_COMMENT_ID_VALUE}"
write_env "COMMAND_COMMENT_AUTHOR" "${COMMAND_COMMENT_AUTHOR_VALUE}"
write_env "COMMAND_REACTION" "${COMMAND_REACTION_VALUE}"
write_env "SIMDECK_BUNDLE_ID" "${SIMDECK_BUNDLE_ID_VALUE}"
write_env "SIMDECK_PORT" "${SIMDECK_PORT_VALUE}"
write_env "SIMDECK_PACKAGE" "${SIMDECK_PACKAGE_VALUE}"
Expand All @@ -128,24 +146,17 @@ runs:
write_env "ARTIFACT_PREFIX" "${ARTIFACT_PREFIX_VALUE}"
write_env "ARTIFACT_NAME_INPUT" "${ARTIFACT_NAME_INPUT_VALUE}"
write_env "FORCE_JAVASCRIPT_ACTIONS_TO_NODE24" "true"
- name: Create status comment and resolve flags
- name: React to command and resolve flags
shell: bash
run: |
set -euo pipefail
status_body="Starting a SimDeck iOS session for this pull request. I will update this comment with the tunnel URL when it is ready."
status_comment_id=""

for attempt in {1..5}; do
if comment_id="$(gh api "repos/${REPO}/issues/${PR_NUMBER}/comments" -f body="${status_body}" --jq '.id')"; then
status_comment_id="${comment_id}"
echo "SIMDECK_STATUS_COMMENT_ID=${status_comment_id}" >> "${GITHUB_ENV}"
break
fi
sleep $((attempt * 5))
done

if [[ -z "${status_comment_id}" ]]; then
exit 1
if [[ -n "${COMMAND_COMMENT_ID:-}" && -n "${COMMAND_REACTION:-}" ]]; then
gh api \
-X POST \
-H "Accept: application/vnd.github+json" \
"repos/${REPO}/issues/comments/${COMMAND_COMMENT_ID}/reactions" \
-f content="${COMMAND_REACTION}" >/dev/null || true
fi

body="${SIMDECK_COMMENT_BODY}"
Expand Down Expand Up @@ -536,17 +547,28 @@ runs:
shell: bash
run: |
set -euo pipefail
mention=""
if [[ -n "${COMMAND_COMMENT_AUTHOR:-}" ]]; then
mention="@${COMMAND_COMMENT_AUTHOR} "
fi

cat > comment.md <<'EOF'
SimDeck iOS session is ready: [Open SimDeck](${{ steps.stream.outputs.url }}?simdeckToken=${{ steps.stream.outputs.access_token }}&device=${{ env.SIMULATOR_UDID }})
__MENTION__SimDeck iOS session is ready: [Open SimDeck](${{ steps.stream.outputs.url }}?simdeckToken=${{ steps.stream.outputs.access_token }}&device=${{ env.SIMULATOR_UDID }})

The selected simulator is booting and the PR app will launch here once its build artifact is installed.

This session will stop after ${{ inputs.keepalive_seconds }} seconds, or earlier if the simulator shuts down.
EOF

body="$(cat comment.md)"
body="${body/__MENTION__/${mention}}"
for attempt in {1..5}; do
if [[ -n "${SIMDECK_STATUS_COMMENT_ID:-}" ]] && gh api -X PATCH "repos/${REPO}/issues/comments/${SIMDECK_STATUS_COMMENT_ID}" -f body="${body}"; then
if [[ -n "${SIMDECK_STATUS_COMMENT_ID:-}" ]]; then
if gh api -X PATCH "repos/${REPO}/issues/comments/${SIMDECK_STATUS_COMMENT_ID}" -f body="${body}"; then
exit 0
fi
elif comment_id="$(gh api "repos/${REPO}/issues/${PR_NUMBER}/comments" -f body="${body}" --jq '.id')"; then
echo "SIMDECK_STATUS_COMMENT_ID=${comment_id}" >> "${GITHUB_ENV}"
exit 0
fi
sleep $((attempt * 5))
Expand Down
29 changes: 17 additions & 12 deletions docs/guide/github-actions.md
Original file line number Diff line number Diff line change
Expand Up @@ -80,18 +80,21 @@ jobs:
with:
pr_number: ${{ github.event.issue.number }}
command: ${{ github.event.comment.body }}
command_comment_id: ${{ github.event.comment.id }}
command_comment_author: ${{ github.event.comment.user.login }}
build_workflow: build-ios-simulator.yml
bundle_id: com.example.app
```

When triggered, the session action:

- creates one status comment and edits that same comment as the session changes;
- reacts to the command comment immediately;
- installs `simdeck` and `cloudflared` on a single macOS runner;
- starts SimDeck with software encoding and the `tiny` stream profile by default;
- prefers `iPhone 17 Pro`, then falls back to the newest available iPhone simulator;
- restores the CoreSimulator device cache when available;
- posts the Cloudflare Tunnel URL only after a simulator UDID has been selected;
- posts the first bot comment only after a simulator UDID has been selected,
mentioning the requester when `command_comment_author` is set;
- downloads the simulator app artifact for the PR head commit, installs it, and
launches it;
- stops after 30 minutes by default, or earlier if the simulator shuts down.
Expand All @@ -115,16 +118,18 @@ Supported quality values are `tiny`, `low`, `economy`, `fast`, `smooth`,

The most common session action inputs are:

| Input | Default | Purpose |
| ------------------- | ------------------------- | -------------------------------------------- |
| `bundle_id` | empty | Fallback app bundle id to launch. |
| `build_workflow` | `build-ios-simulator.yml` | Workflow file that uploads the app artifact. |
| `artifact_prefix` | `ios-simulator-app` | Prefix used for `<prefix>-<sha>` artifacts. |
| `simdeck_version` | `latest` | npm version or dist-tag to install. |
| `stream_profile` | `tiny` | Default stream quality profile. |
| `simulator_name` | `iPhone 17 Pro` | Preferred simulator device name. |
| `keepalive_seconds` | `1800` | Session lifetime after app launch. |
| `simulator_cache` | `true` | Restore and save CoreSimulator device cache. |
| Input | Default | Purpose |
| ------------------------ | ------------------------- | --------------------------------------------- |
| `bundle_id` | empty | Fallback app bundle id to launch. |
| `build_workflow` | `build-ios-simulator.yml` | Workflow file that uploads the app artifact. |
| `command_comment_id` | empty | Comment id to react to immediately. |
| `command_comment_author` | empty | GitHub user to mention when the URL is ready. |
| `artifact_prefix` | `ios-simulator-app` | Prefix used for `<prefix>-<sha>` artifacts. |
| `simdeck_version` | `latest` | npm version or dist-tag to install. |
| `stream_profile` | `tiny` | Default stream quality profile. |
| `simulator_name` | `iPhone 17 Pro` | Preferred simulator device name. |
| `keepalive_seconds` | `1800` | Session lifetime after app launch. |
| `simulator_cache` | `true` | Restore and save CoreSimulator device cache. |

The caller workflow owns job-level settings such as `runs-on`,
`timeout-minutes`, permissions, and concurrency. Pin `NativeScript/SimDeck` to a
Expand Down
Loading