actions / runner-images

GitHub Actions runner images
MIT License
10.15k stars 3.06k forks source link

macOS cant run most of Apple Scripts because of UI block #553

Closed Shchvova closed 4 years ago

Shchvova commented 4 years ago

Describe the bug

I'm trying to build a DMG using GitHub actions, but it involves popular tool create_dmg which utilizes Apple Script. Problem is, it shows up a request for permissions, which one doesn't even have to be admin to accept. But since

image
# this resets granted permissions, if you want to test it locally. No sudo required.
# tccutil reset AppleEvents
# simple script to close all finder windows. In GitHub action this will timeout
osascript -e 'tell application "Finder" to close windows'

Area for Triage: Scripting and command line Apple

Question, Bug, or Feature?: Bug

Virtual environments affected

Expected behavior OSAScripts to execute instantly. One doesn't have to be an admin to allow this, just regular user. Also, once allowed, it will keep the behaviour. May be include this permissions in base image?

Actual behavior It fails because of timeout, waiting for the GUI. No one there to click the button. This just sad. Here is example of failing action

name: OSA Script Failure
on: push
jobs:
  fail:
    runs-on: macos-latest
    steps:
      - run: osascript -e 'tell application "Finder" to close windows'

It may seem like this is related to the #113, but Full Disk Access is much more dramatic permission to ask, and with full disk access, indeed, one can change contents of the TCC.db, which is sqlite3 database containing permissions, with lots of hacks. But this is rather sub-case, requiring way less intrusion into the OS.

Shchvova commented 4 years ago

For my specific case I solved the issue with using another tool, https://github.com/sindresorhus/create-dmg

maxim-lobanov commented 4 years ago

@Shchvova , thank you for your report and fix. Unfortunately, we didn't have a chance to provide quick workaround for this issue because of the enabled SIP on Hosted macOS images. It prevents modifying system files and this issue can't be resolved in runtime.

We are looking at the ways to solve this problem globally but not solution and ETA for now.

Shchvova commented 4 years ago

That’s alright. To be honest, ability to build open source macOS Apps for free in such a comfortable way is amazing by itself.

paulz commented 4 years ago

We are experiencing the same issue. Please allow running osascript for Mac actions.

Currently the image starts with open Finder windows and some of them are blocking our UI tests. When we try to close Finder windows we get this error.

Run osascript -e 'tell application "Finder" to close every window'
29:47: execution error: Finder got an error: AppleEvent timed out. (-1712)
##[error]Process completed with exit code 1.
miketimofeev commented 4 years ago

@Shchvova @paulz we've added support for running Apple Scripts on the system. The changes will be deployed next week. Thank you!

paulz commented 4 years ago

Thank you, so much @miketimofeev! We temporarily went to hosted action and looking forward to return back to GitHub virtual environments. Apple Scripts are huge help for us in macOS test automation.

miketimofeev commented 4 years ago

Unfortunately, we have found another issue with Apple Script on macOS 10.15 so the fix won't be included in the next week's VM image.

paulz commented 4 years ago

Thank you, we have a workaround for now to close Finder without Apple Script:

# Close Finder
launchctl unload /System/Library/LaunchAgents/com.apple.Finder.plist
# Close Notification window
killall UserNotificationCenter || true

as suggested here: https://github.com/actions/virtual-environments/issues/977#issuecomment-639087879

But we need Apple Script for other tasks in the UI Tests, especially to ability to control other applications. It would be great if osascript would be in the whitelist for Privacy in particular for Screen Recording and Accessibility. Or if we can control Security & Privacy settings or have SIP disabled image.

miketimofeev commented 4 years ago

@Shchvova @paulz the image with Apple Script support has been successfully deployed. This works fine now:

  set -e
  echo "tell application \"System Events\"
  click at {123,456}
  end tell
  " > b.scpt
  osascript b.scpt
  shell: /bin/bash -e {0}
group 1 of scroll area 1 of application process Finder

I'm going to close the issue, but feel free to contact us if you have any concerns. Thank you!

paulz commented 4 years ago

Trying to run the Apple Script even with sudo

  sudo osascript -e 'tell application "Finder" to close windows' || true

I am getting timeout error:

execution error: Finder got an error: AppleEvent timed out. (-1712)

https://github.com/sparta-science/MacSwitchActivation/runs/792253844?check_suite_focus=true#step:3:4

@miketimofeev do you have a link to successful run of an apple script?

miketimofeev commented 4 years ago

@paulz here it is https://github.com/miketimofeev/actionstest/runs/792596066?check_suite_focus=true But I've tried sudo osascript -e 'tell application "Finder" to close windows' and it didn't work because of another permission request image I'm going to fix it next week. Thanks for your patience!

miketimofeev commented 4 years ago

@paulz I've succeeded in finding the necessary permissions, a new VM image will be deployed next week. The following workaround can be used until then

jobs:
  build:
    runs-on: macos-latest
    steps:
      - uses: actions/checkout@v2
      - name: test osa
        shell: bash
        run: |
          sqlite3 "/Users/runner/Library/Application Support/com.apple.TCC/TCC.db" "insert into access (service, client, client_type, allowed, prompt_count, indirect_object_identifier_type, indirect_object_identifier) values ('kTCCServiceAppleEvents', '/bin/bash', 1, 1, 1, 0, 'com.apple.finder')"
          osascript -e 'tell application "Finder" to close windows'
paulz commented 4 years ago

it worked! https://github.com/sparta-science/connect/runs/802016625?check_suite_focus=true#step:3:3 Thank you, @miketimofeev!

How would can we check if new image has been deployed?

Would we see a new version in the setup job step? What we have there now is:

  Environment: macos-10.15
  Version: 20200610.3
miketimofeev commented 4 years ago

@paulz we're currently deploying this vm image, which doesn't include related changes: https://github.com/actions/virtual-environments/releases/tag/macos-10.15%2F20200618.1 I'll notify you when the fixed VM image is deployed.

miketimofeev commented 4 years ago

@paulz @Shchvova The 10.15 image with the fix has been deployed, however, AzDO 10.14 macOS image will be fixed in next week's deployment so I'm going to leave this issue open for one more week.

paulz commented 4 years ago

Thank you, 🙏, confirming it works for me now:

on the new version of the Virtual Environment:

Virtual Environment Environment: macos-10.15 Version: 20200625.2

Version: 20200625.2 https://github.com/sparta-science/MacSwitchActivation/runs/835626937?check_suite_focus=true#step:3:2 run successfully executing this apple script:

sudo osascript -e 'tell application "Finder" to close windows'

Version: 20200610.3 was failing with timeout error: https://github.com/sparta-science/MacSwitchActivation/runs/835612190?check_suite_focus=true#step:3:4

29:42: execution error: Finder got an error: AppleEvent timed out. (-1712)

Hard to notice, but when we rerun previous failure it's still runs on the old image. https://github.com/sparta-science/MacSwitchActivation/runs/835626937?check_suite_focus=true#step:1:8 and reports it did run days ago. Is it how it supposed to look? Or is there another view of all runs of a particular commit?

miketimofeev commented 4 years ago

@Shchvova @paulz apple script works on both GitHub actions and AzDO. I'm going to close the issue, but feel free to contact us if you have any concerns. Thank you!

hendriks73 commented 3 years ago

Hi,

I'm using

sqlite3 "/Users/runner/Library/Application Support/com.apple.TCC/TCC.db" "insert into access (service, client, client_type, allowed, prompt_count, indirect_object_identifier_type, indirect_object_identifier) values ('kTCCServiceAppleEvents', '/bin/bash', 1, 1, 1, 0, 'com.apple.Photos')"

before running AppleScripts against the Photos.app, but pretty much regardless what I run, I always get a timeout (on macos-latest).

NSAppleScriptErrorAppName = Photos;
NSAppleScriptErrorBriefMessage = "AppleEvent timed out.";
NSAppleScriptErrorMessage = "Photos got an error: AppleEvent timed out.";
NSAppleScriptErrorNumber = "-1712";
NSAppleScriptErrorRange = "NSRange: {34, 6}";

Is it possible that the Photos.app is caught in some sort of "run for the first time" modal dialog and therefore does not react to AppleScripts?

Thanks.

miketimofeev commented 3 years ago

Hi @hendriks73! Yes, it's possible. If you are able to provide the AppleScript failing on the execution then we can try it on the VM and see what the exact pop-up it is.

hendriks73 commented 3 years ago

Cool. Please see https://github.com/hendriks73/applescriptphotosworkflow Thank you!

hendriks73 commented 3 years ago

This is just for demo purposes:

jobs:
  build:

    runs-on: macos-latest

    steps:
      - name: Attempt to call stuff on Photos via AppleScript
        shell: bash
        # Manipulate TCC, see https://github.com/actions/virtual-environments/issues/553#issuecomment-648109166
        # in order to allow AppleScript automation of Photos.app
        run: |
          sqlite3 "/Users/runner/Library/Application Support/com.apple.TCC/TCC.db" "insert into access (service, client, client_type, allowed, prompt_count, indirect_object_identifier_type, indirect_object_identifier) values ('kTCCServiceAppleEvents', '/bin/bash', 1, 1, 1, 0, 'com.apple.Photos')"
          osascript -e "tell application \"Photos\" to return albums"
miketimofeev commented 3 years ago

@hendriks73 there is an error in the insert query Error: table access has no column named allowed

hendriks73 commented 3 years ago

Where do you see that error message?

The insert statement is a verbatim copy of yours from https://github.com/actions/virtual-environments/issues/553#issuecomment-648109166 - except for the bundle id.

And it seems to work really well for other scriptable apps.

hendriks73 commented 3 years ago

My run (i.e. the logs) of the workflow is here.

miketimofeev commented 3 years ago

sorry, I've missed the fact that your run is on macOS-10.15 and tried it on macOS-11, where the DB structure is different. Will give it a try on macOS-10.15

hendriks73 commented 3 years ago

Sorry, should have mentioned that.

If you'd like to do people a favor, please post the equivalent insert statement for macOS 11 here. Would be very much appreciated (at least by me :-) ).

miketimofeev commented 3 years ago

@hendriks73 probably macOS-11 would be pretty the same except the column. For the initial issue, I've found the root cause — the photos app needs to be activated first, otherwise, it is stuck. image

This can be done using this simple apple script

tell application "Photos"
    activate
    tell application "System Events" to key code 36 #return
end tell

The whole workflow looks something like this

          sqlite3 "/Users/runner/Library/Application Support/com.apple.TCC/TCC.db" "insert into access (service, client, client_type, allowed, prompt_count, indirect_object_identifier_type, indirect_object_identifier) values ('kTCCServiceAppleEvents', '/bin/bash', 1, 1, 1, 0, 'com.apple.Photos')"
          osascript activate.script
          osascript -e "tell application \"Photos\" to return albums"
hendriks73 commented 3 years ago

Awesome. Thank you for looking into this!

I've incorporated the activation script into my actual project https://github.com/hendriks73/japlphoto (Java API for Photos) and it seems to work like a charm.

TomasHubelbauer commented 1 year ago

@hendriks73 did you ever figure out the Error: table access has no column named allowed issue? I am trying to add a permission for Apple Notes and ran into the same error. I removed the column, then I got the same error but for prompt_count. Removed that, too, now I get this:

NOT NULL constraint failed: access.auth_value