Omarchy 4.0.3 #291
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: Omarchy 4.0.3 | |
| run-name: Omarchy 4.0.3 | |
| on: | |
| push: | |
| branches: [main] | |
| paths: &e2e-paths | |
| - ".github/workflows/midscene-omarchy-4.0.3.yml" | |
| - ".github/workflows/deploy-midscene-report.yml" | |
| - "scripts/build-pages-report.mjs" | |
| - "scripts/report-cases.mjs" | |
| - "scripts/render-ci-report-summary.mjs" | |
| - "scripts/write-ci-shard-status.mjs" | |
| - "scripts/verify-pages-report.mjs" | |
| - "scripts/verify-omarchy-evidence.mjs" | |
| - "scripts/omarchy-shell-evidence.mjs" | |
| - "scripts/parse-omarchy-review-issue.mjs" | |
| - "tests/contracts/test_pages_report_history.mjs" | |
| - "tests/contracts/test_model_rate_gate.mjs" | |
| - "tests/contracts/test_omarchy_review_issue.mjs" | |
| - "tests/e2e/package.json" | |
| - "tests/e2e/package-lock.json" | |
| - "tests/e2e/gtk_fixture.py" | |
| - "tests/e2e/gtk_onboarding_fixture.py" | |
| - "tests/e2e/gtk_runtime_fixture.py" | |
| - "tests/e2e/capture-report-preview.mjs" | |
| - "tests/e2e/cases/**" | |
| - "tests/e2e/midscene.config.ts" | |
| - "tests/e2e/model-rate-gate.mjs" | |
| - "tests/e2e/render-omarchy-plugin-smoke.mjs" | |
| - "tests/e2e/run-omarchy-midscene.sh" | |
| - "tests/e2e/restore-omarchy-vm.sh" | |
| - "tests/e2e/omarchy-vm.env" | |
| - "src/**" | |
| - "manifest.json" | |
| - "install.sh" | |
| - "setup-omarchy.sh" | |
| - "start.sh" | |
| - "omarchy/**" | |
| pull_request: | |
| branches: [main] | |
| paths: *e2e-paths | |
| issues: | |
| types: [labeled] | |
| workflow_dispatch: | |
| inputs: | |
| bootstrap_hosted_model: | |
| description: Transfer the existing hosted model secret to the Midscene App | |
| type: boolean | |
| required: false | |
| default: false | |
| project: | |
| description: Run one Midscene project for focused verification | |
| type: choice | |
| default: all | |
| options: | |
| - all | |
| - omarchy-shard-1 | |
| - omarchy-shard-2 | |
| - omarchy-shard-3 | |
| - omarchy-shard-4 | |
| - omarchy-shell | |
| - omarchy-plugin-review | |
| - omarchy-plugin-smoke | |
| - omarchy-providers | |
| plugin_repository: | |
| description: Public GitHub owner/repository for omarchy-plugin-smoke | |
| type: string | |
| required: false | |
| plugin_sha: | |
| description: Exact 40-character commit SHA for omarchy-plugin-smoke | |
| type: string | |
| required: false | |
| plugin_id: | |
| description: Plugin manifest ID for omarchy-plugin-smoke | |
| type: string | |
| required: false | |
| plugin_open_method: | |
| description: Use summon for panel/overlay/menu, or a plugin IPC method such as open | |
| type: string | |
| required: false | |
| default: open | |
| visible_assertion: | |
| description: What should be visible after opening the plugin | |
| type: string | |
| required: false | |
| review_run_id: | |
| description: Midscene GitHub App review run ID | |
| type: string | |
| required: false | |
| permissions: | |
| contents: read | |
| packages: read | |
| id-token: write | |
| concurrency: | |
| group: midscene-model-e2e-${{ github.workflow }}-${{ github.event.issue.number || github.ref }} | |
| cancel-in-progress: ${{ github.event_name == 'pull_request' }} | |
| jobs: | |
| bootstrap-hosted-model: | |
| name: Bootstrap hosted model | |
| if: github.event_name == 'workflow_dispatch' && inputs.bootstrap_hosted_model == true && github.actor == 'quanru' && github.ref == 'refs/heads/research/omarchy-plugin-visual-review' | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 5 | |
| env: | |
| MIDSCENE_REVIEW_APP_URL: ${{ vars.MIDSCENE_REVIEW_APP_URL }} | |
| HOSTED_MODEL_API_KEY: ${{ secrets.MIDSCENE_MODEL_API_KEY }} | |
| HOSTED_MODEL_NAME: ${{ secrets.MIDSCENE_MODEL_NAME }} | |
| HOSTED_MODEL_BASE_URL: ${{ secrets.MIDSCENE_MODEL_BASE_URL }} | |
| HOSTED_MODEL_FAMILY: ${{ secrets.MIDSCENE_MODEL_FAMILY }} | |
| steps: | |
| - name: Transfer hosted model configuration over OIDC-authenticated HTTPS | |
| run: | | |
| test -n "$MIDSCENE_REVIEW_APP_URL" | |
| test -n "$HOSTED_MODEL_API_KEY" | |
| test -n "$HOSTED_MODEL_NAME" | |
| test -n "$HOSTED_MODEL_BASE_URL" | |
| test -n "$HOSTED_MODEL_FAMILY" | |
| node --input-type=module <<'JS' | |
| const identityResponse = await fetch(`${process.env.ACTIONS_ID_TOKEN_REQUEST_URL}&audience=midscene-review-app`, { | |
| headers: { authorization: `bearer ${process.env.ACTIONS_ID_TOKEN_REQUEST_TOKEN}` }, | |
| }); | |
| if (!identityResponse.ok) throw new Error(`GitHub OIDC failed: ${identityResponse.status}`); | |
| const { value: identity } = await identityResponse.json(); | |
| const response = await fetch(`${process.env.MIDSCENE_REVIEW_APP_URL.replace(/\/+$/, '')}/api/worker/bootstrap-hosted`, { | |
| method: 'POST', | |
| headers: { authorization: `Bearer ${identity}`, 'content-type': 'application/json' }, | |
| body: JSON.stringify({ | |
| apiKey: process.env.HOSTED_MODEL_API_KEY, | |
| modelName: process.env.HOSTED_MODEL_NAME, | |
| baseUrl: process.env.HOSTED_MODEL_BASE_URL, | |
| modelFamily: process.env.HOSTED_MODEL_FAMILY, | |
| }), | |
| }); | |
| if (!response.ok) throw new Error(`Midscene bootstrap failed: ${response.status}`); | |
| console.log('Hosted model configuration was stored by the Midscene review service.'); | |
| JS | |
| omarchy-e2e: | |
| name: Midscene visual (${{ matrix.project }}) | |
| if: >- | |
| inputs.bootstrap_hosted_model != true && | |
| (github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository) && | |
| (github.event_name != 'issues' || | |
| (github.event.label.name == 'midscene-review' && startsWith(github.event.issue.title, '[Omarchy review] '))) | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 60 | |
| strategy: | |
| # Each shard restores an independent disposable VM. Sharing one Hyprland | |
| # session would make fixture resets, focus and screenshots race. | |
| # Run independent VMs concurrently. Each worker paces model requests to | |
| # one every 20s, keeping the aggregate below the Ark endpoint RPM. | |
| fail-fast: false | |
| max-parallel: 5 | |
| matrix: | |
| project: >- | |
| ${{ fromJSON(github.event_name == 'issues' && '["omarchy-plugin-smoke"]' || | |
| (inputs.project != '' && inputs.project != 'all') && | |
| format('["{0}"]', inputs.project) || | |
| '["omarchy-shard-1","omarchy-shard-2","omarchy-shard-3","omarchy-shard-4","omarchy-shell"]') }} | |
| env: | |
| MIDSCENE_COMPUTER_HEADLESS_LINUX: "true" | |
| MIDSCENE_REPLANNING_CYCLE_LIMIT: "40" | |
| # The Ark endpoint answers bursts with 429; retry up to 3 extra times | |
| # with a 65s fixed pause so the wait spans the 60s RPM window. | |
| MIDSCENE_MODEL_RETRY_COUNT: "3" | |
| MIDSCENE_MODEL_RETRY_INTERVAL: "65000" | |
| # The configured model endpoint is reachable over IPv4; disabling Node's | |
| # family race avoids intermittent runner-side IPv6 connection timeouts. | |
| NODE_OPTIONS: "--dns-result-order=ipv4first --no-network-family-autoselection" | |
| REVIEW_PLUGIN_REPOSITORY: ${{ inputs.plugin_repository }} | |
| REVIEW_PLUGIN_SHA: ${{ inputs.plugin_sha }} | |
| REVIEW_PLUGIN_ID: ${{ inputs.plugin_id }} | |
| REVIEW_PLUGIN_OPEN_METHOD: ${{ inputs.plugin_open_method }} | |
| REVIEW_VISIBLE_ASSERTION: ${{ inputs.visible_assertion }} | |
| MIDSCENE_REVIEW_APP_URL: ${{ vars.MIDSCENE_REVIEW_APP_URL }} | |
| steps: | |
| - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 | |
| with: | |
| persist-credentials: false | |
| - name: Read maintainer-approved review Issue | |
| if: github.event_name == 'issues' | |
| run: node scripts/parse-omarchy-review-issue.mjs | |
| - name: Configure existing worker model | |
| if: github.event_name != 'workflow_dispatch' || inputs.review_run_id == '' | |
| env: | |
| LEGACY_MODEL_API_KEY: ${{ secrets.MIDSCENE_MODEL_API_KEY }} | |
| LEGACY_MODEL_NAME: ${{ secrets.MIDSCENE_MODEL_NAME }} | |
| LEGACY_MODEL_BASE_URL: ${{ secrets.MIDSCENE_MODEL_BASE_URL }} | |
| LEGACY_MODEL_FAMILY: ${{ secrets.MIDSCENE_MODEL_FAMILY }} | |
| LEGACY_MODEL_REASONING_ENABLED: ${{ secrets.MIDSCENE_MODEL_REASONING_ENABLED }} | |
| run: | | |
| { | |
| echo "MIDSCENE_MODEL_API_KEY=$LEGACY_MODEL_API_KEY" | |
| echo "MIDSCENE_MODEL_NAME=$LEGACY_MODEL_NAME" | |
| echo "MIDSCENE_MODEL_BASE_URL=$LEGACY_MODEL_BASE_URL" | |
| echo "MIDSCENE_MODEL_FAMILY=$LEGACY_MODEL_FAMILY" | |
| echo "MIDSCENE_MODEL_REASONING_ENABLED=$LEGACY_MODEL_REASONING_ENABLED" | |
| } >> "$GITHUB_ENV" | |
| - name: Obtain scoped Midscene model proxy token | |
| if: github.event_name == 'workflow_dispatch' && inputs.review_run_id != '' | |
| env: | |
| REVIEW_RUN_ID: ${{ inputs.review_run_id }} | |
| run: | | |
| test -n "$MIDSCENE_REVIEW_APP_URL" | |
| oidc=$(curl --fail --silent --show-error \ | |
| -H "Authorization: bearer $ACTIONS_ID_TOKEN_REQUEST_TOKEN" \ | |
| "${ACTIONS_ID_TOKEN_REQUEST_URL}&audience=midscene-review-app" | jq -r '.value') | |
| response=$(curl --fail --silent --show-error \ | |
| -H "Authorization: Bearer $oidc" \ | |
| -H "Content-Type: application/json" \ | |
| --data "$(jq -nc --arg id "$REVIEW_RUN_ID" '{runId:$id}')" \ | |
| "${MIDSCENE_REVIEW_APP_URL%/}/api/worker/model-token") | |
| proxy_token=$(jq -er '.token' <<< "$response") | |
| echo "::add-mask::$proxy_token" | |
| { | |
| echo "MIDSCENE_MODEL_API_KEY=$proxy_token" | |
| echo "MIDSCENE_MODEL_NAME=$(jq -er '.modelName' <<< "$response")" | |
| echo "MIDSCENE_MODEL_FAMILY=$(jq -er '.modelFamily' <<< "$response")" | |
| echo "MIDSCENE_MODEL_BASE_URL=$(jq -er '.baseUrl' <<< "$response")" | |
| } >> "$GITHUB_ENV" | |
| - name: Require Midscene model configuration | |
| run: | | |
| test -n "$MIDSCENE_MODEL_API_KEY" | |
| test -n "$MIDSCENE_MODEL_NAME" | |
| test -n "$MIDSCENE_MODEL_BASE_URL" | |
| test -n "$MIDSCENE_MODEL_FAMILY" | |
| - name: Validate plugin review request | |
| if: matrix.project == 'omarchy-plugin-smoke' | |
| run: | | |
| [[ "$REVIEW_PLUGIN_REPOSITORY" =~ ^[A-Za-z0-9_.-]+/[A-Za-z0-9_.-]+$ ]] | |
| [[ "$REVIEW_PLUGIN_SHA" =~ ^[a-fA-F0-9]{40}$ ]] | |
| [[ "$REVIEW_PLUGIN_ID" =~ ^[a-z0-9][a-z0-9._-]{2,127}$ ]] | |
| [[ "$REVIEW_PLUGIN_OPEN_METHOD" =~ ^[A-Za-z][A-Za-z0-9_]*$ ]] | |
| test -n "$REVIEW_VISIBLE_ASSERTION" | |
| test "${#REVIEW_VISIBLE_ASSERTION}" -le 500 | |
| - name: Check Midscene model before the expensive VM install | |
| run: | | |
| payload=$(jq -nc --arg model "$MIDSCENE_MODEL_NAME" '{ | |
| model: $model, | |
| messages: [{role: "user", content: "Reply OK."}], | |
| max_tokens: 1 | |
| }') | |
| curl --fail --silent --show-error \ | |
| --connect-timeout 15 --max-time 90 \ | |
| --retry 4 --retry-all-errors --retry-delay 5 --retry-max-time 90 \ | |
| -H "Authorization: Bearer $MIDSCENE_MODEL_API_KEY" \ | |
| -H "Content-Type: application/json" \ | |
| --data "$payload" \ | |
| "${MIDSCENE_MODEL_BASE_URL%/}/chat/completions" \ | |
| >/dev/null | |
| - name: Install ORAS client | |
| uses: oras-project/setup-oras@1d808f7d7f6995cc68b7bf507bfe5c5446e1dc9d # v2.0.1 | |
| - name: Sign in to GitHub Container Registry | |
| run: echo "$GHCR_TOKEN" | oras login ghcr.io --username "$GITHUB_ACTOR" --password-stdin | |
| env: | |
| GHCR_TOKEN: ${{ github.token }} | |
| - name: Restore prebuilt Omarchy VM | |
| run: tests/e2e/restore-omarchy-vm.sh | |
| - uses: actions/setup-node@249970729cb0ef3589644e2896645e5dc5ba9c38 # v6.5.0 | |
| with: | |
| node-version: "22" | |
| cache: npm | |
| cache-dependency-path: tests/e2e/package-lock.json | |
| - name: Install Midscene and VNC bridge | |
| id: test-dependencies | |
| run: | | |
| sudo apt-get install -y --no-install-recommends \ | |
| fluxbox tigervnc-viewer x11-xserver-utils xvfb | |
| for attempt in 1 2 3; do | |
| if npm --prefix tests/e2e ci --include=optional --ignore-scripts; then | |
| exit 0 | |
| fi | |
| echo "npm install attempt $attempt failed; retrying." >&2 | |
| sleep 10 | |
| done | |
| exit 1 | |
| - name: Run real Omarchy Midscene project | |
| id: midscene-test | |
| env: | |
| PROJECT: ${{ matrix.project }} | |
| run: tests/e2e/run-omarchy-midscene.sh "$PROJECT" | |
| - name: Capture report evidence | |
| id: capture-report | |
| if: always() && !cancelled() && steps.test-dependencies.outcome == 'success' | |
| env: | |
| PROJECT: ${{ matrix.project }} | |
| run: | | |
| node tests/e2e/capture-report-preview.mjs \ | |
| --report-dir tests/e2e/midscene_run \ | |
| --projects "$PROJECT" | |
| - name: Record shard result for report aggregation | |
| if: always() && !cancelled() | |
| env: | |
| PROJECT: ${{ matrix.project }} | |
| TEST_OUTCOME: ${{ steps.midscene-test.outcome }} | |
| CAPTURE_OUTCOME: ${{ steps.capture-report.outcome }} | |
| run: | | |
| node scripts/write-ci-shard-status.mjs \ | |
| --output "tests/e2e/midscene_run/ci-shard-status-$PROJECT.json" \ | |
| --project "$PROJECT" \ | |
| --test-outcome "${TEST_OUTCOME:-skipped}" \ | |
| --capture-outcome "${CAPTURE_OUTCOME:-skipped}" | |
| - name: Upload installer evidence | |
| if: always() && !cancelled() | |
| uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 | |
| with: | |
| name: omarchy-vm-installer-evidence-${{ matrix.project }} | |
| path: .midscene-omarchy/omarchy-iso/test-runs/**/runs/** | |
| if-no-files-found: warn | |
| retention-days: 3 | |
| overwrite: true | |
| - name: Upload Omarchy Midscene shard report | |
| if: always() && !cancelled() | |
| uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 | |
| with: | |
| name: omarchy-midscene-${{ matrix.project }} | |
| path: tests/e2e/midscene_run/ | |
| if-no-files-found: error | |
| retention-days: 7 | |
| overwrite: true | |
| - name: Publish direct HTML report to Midscene | |
| id: publish-report | |
| if: always() && !cancelled() && github.event_name == 'workflow_dispatch' && inputs.review_run_id != '' | |
| continue-on-error: true | |
| env: | |
| REVIEW_RUN_ID: ${{ inputs.review_run_id }} | |
| run: | | |
| oidc=$(curl --fail --silent --show-error \ | |
| -H "Authorization: bearer $ACTIONS_ID_TOKEN_REQUEST_TOKEN" \ | |
| "${ACTIONS_ID_TOKEN_REQUEST_URL}&audience=midscene-review-app" | jq -r '.value') | |
| report_root=$(find tests/e2e/midscene_run/report -mindepth 1 -maxdepth 1 -type d -name 'midscene-e2e-*' -print -quit) | |
| test -f "$report_root/index.html" | |
| while IFS= read -r -d '' file; do | |
| relative=${file#"$report_root"/} | |
| if grep -Fq -- "$MIDSCENE_MODEL_API_KEY" "$file"; then | |
| echo "Refusing to publish a report containing the model proxy token." >&2 | |
| exit 1 | |
| fi | |
| curl --fail --silent --show-error \ | |
| -X PUT -H "Authorization: Bearer $oidc" \ | |
| --data-binary @"$file" \ | |
| "${MIDSCENE_REVIEW_APP_URL%/}/api/worker/report/$REVIEW_RUN_ID/$relative" >/dev/null | |
| done < <(find "$report_root" -type f -print0) | |
| - name: Complete Midscene review check | |
| if: always() && !cancelled() && github.event_name == 'workflow_dispatch' && inputs.review_run_id != '' | |
| env: | |
| REVIEW_RUN_ID: ${{ inputs.review_run_id }} | |
| TEST_OUTCOME: ${{ steps.midscene-test.outcome }} | |
| REPORT_OUTCOME: ${{ steps.publish-report.outcome }} | |
| run: | | |
| if [ "$REPORT_OUTCOME" = success ]; then sleep 65; fi | |
| oidc=$(curl --fail --silent --show-error \ | |
| -H "Authorization: bearer $ACTIONS_ID_TOKEN_REQUEST_TOKEN" \ | |
| "${ACTIONS_ID_TOKEN_REQUEST_URL}&audience=midscene-review-app" | jq -r '.value') | |
| outcome=failed | |
| if [ "$TEST_OUTCOME" = success ] && [ "$REPORT_OUTCOME" = success ]; then outcome=succeeded; fi | |
| curl --fail --silent --show-error \ | |
| -H "Authorization: Bearer $oidc" \ | |
| -H "Content-Type: application/json" \ | |
| --data "$(jq -nc --arg id "$REVIEW_RUN_ID" --arg status "$outcome" '{runId:$id,outcome:$status}')" \ | |
| "${MIDSCENE_REVIEW_APP_URL%/}/api/worker/complete" >/dev/null | |
| - name: Verify Omarchy shell visual evidence | |
| if: success() && matrix.project == 'omarchy-shell' | |
| run: node scripts/verify-omarchy-evidence.mjs tests/e2e/midscene_run | |
| report-bundle: | |
| name: Assemble Midscene report bundle | |
| needs: omarchy-e2e | |
| if: >- | |
| always() && !cancelled() && github.event_name != 'issues' && inputs.bootstrap_hosted_model != true && | |
| (inputs.project == '' || inputs.project == 'all') | |
| runs-on: ubuntu-latest | |
| outputs: | |
| report-artifact-id: ${{ steps.report.outputs.artifact-id }} | |
| steps: | |
| - name: Create bundle even when every shard failed early | |
| run: | | |
| mkdir -p "$RUNNER_TEMP/midscene-report-shards" | |
| printf '%s\n' '{"bundle":"omarchy-4.0.3"}' > "$RUNNER_TEMP/midscene-report-shards/ci-bundle-status.json" | |
| # Keep shard directories separate. Native report filenames can share a | |
| # timestamp, while the Pages builder locates reports by project identity. | |
| - name: Download every shard report | |
| uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 | |
| with: | |
| # Exclude the previous attempt's combined omarchy-midscene-e2e-report | |
| # artifact when rerunning failed shards of the same workflow run. | |
| pattern: omarchy-midscene-omarchy-* | |
| path: ${{ runner.temp }}/midscene-report-shards | |
| merge-multiple: false | |
| - name: Upload combined report bundle | |
| id: report | |
| uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 | |
| with: | |
| name: omarchy-midscene-e2e-report | |
| path: ${{ runner.temp }}/midscene-report-shards/ | |
| if-no-files-found: error | |
| retention-days: 7 | |
| overwrite: true | |
| pages-report: | |
| name: GitHub Pages report | |
| needs: [omarchy-e2e, report-bundle] | |
| if: >- | |
| always() && github.event_name != 'issues' && inputs.bootstrap_hosted_model != true && | |
| !cancelled() && | |
| needs.report-bundle.outputs.report-artifact-id != '' && | |
| (github.event_name != 'pull_request' || | |
| github.event.pull_request.head.repo.full_name == github.repository) | |
| permissions: | |
| actions: read | |
| contents: read | |
| pages: write | |
| id-token: write | |
| uses: ./.github/workflows/deploy-midscene-report.yml | |
| with: | |
| artifact-name: omarchy-midscene-e2e-report | |
| report-label: Omarchy 4.0.3 | |
| summary-title: Omarchy | |
| report-groups: >- | |
| [{"role":"primary","label":"Doubao Say","projects":["omarchy-shard-1","omarchy-shard-2","omarchy-shard-3","omarchy-shard-4"]},{"role":"auxiliary","label":"Omarchy visual checks","projects":["omarchy-shell"]}] | |
| run-result: ${{ needs.omarchy-e2e.result }} | |
| review-issue-result: | |
| name: Link visual evidence to review request | |
| needs: omarchy-e2e | |
| if: >- | |
| always() && github.event_name == 'issues' && | |
| github.event.label.name == 'midscene-review' && | |
| startsWith(github.event.issue.title, '[Omarchy review] ') | |
| runs-on: ubuntu-latest | |
| permissions: | |
| issues: write | |
| env: | |
| GH_TOKEN: ${{ github.token }} | |
| ISSUE_NUMBER: ${{ github.event.issue.number }} | |
| REVIEW_RESULT: ${{ needs.omarchy-e2e.result }} | |
| steps: | |
| - name: Comment with CI run and artifact | |
| run: | | |
| cat > "$RUNNER_TEMP/omarchy-review-comment.md" <<EOF | |
| Midscene Omarchy visual review CI: **${REVIEW_RESULT}**. | |
| [Open the GitHub Actions run](${GITHUB_SERVER_URL}/${GITHUB_REPOSITORY}/actions/runs/${GITHUB_RUN_ID}) and download the omarchy-midscene-omarchy-plugin-smoke artifact for the native report and screenshots. | |
| This is behavioral evidence from a disposable VM. It does not change the Marketplace security baseline or Verified status. A failed run needs its logs reviewed before attributing the failure to the plugin. | |
| EOF | |
| gh issue comment "$ISSUE_NUMBER" --repo "$GITHUB_REPOSITORY" --body-file "$RUNNER_TEMP/omarchy-review-comment.md" |