Home > Software design >  Exit command early if waiting for user interaction from stdin
Exit command early if waiting for user interaction from stdin

Time:11-16

Currently I am using fastlane to build an iOS app on a local gitlab runner.

Here is the part of the script my question is focused on:

    - bundle exec fastlane cert -u ${ENTERPRISE_APPLE_ID}
    - bundle exec fastlane sigh -a ${PROVISIONING_PROFILE_IDENTIFIER} username:${ENTERPRISE_APPLE_ID}
    - bundle exec fastlane gym --clean --export_method enterprise --output_name "APP-${TAG}"

There is a lot of answers on this site related to fastlane and authentication such as this but they mostly focus on App Store Connect, not enterprise accounts. Currently I am following the suggestions from the fastlane docs about storing a session on my ci machine.

The problem is after a month the session expires and the fastlane command keeps trying to auth via two factor leading to me being temporarily locked out of my account for too many attempts within 24 hours. See below for the CI logs.

18:27:18]: Starting login with user 'my@apple.id'
Available session is not valid any more. Continuing with normal login.
Session loaded from environment variable is not valid. Continuing with normal login.
Two-factor Authentication (6 digits code) is enabled for account 'my@apple.id'
More information about Two-factor Authentication: https://support.apple.com/en-us/HT204915
If you're running this in a non-interactive session (e.g. server or CI)
check out https://github.com/fastlane/fastlane/tree/master/spaceship#2-step-verification
Please enter the 6 digit code you received at  1 (•••) •••-••14:
Requesting session...
Error: Incorrect verification code
Please enter the 6 digit code you received at  1 (•••) •••-••14:
Requesting session...
Error: Incorrect verification code
Please enter the 6 digit code you received at  1 (•••) •••-••14:
Requesting session...

My question is: is it possible to tell if this command is requiring user input so I can just exit the command and then manually refresh the session?

CodePudding user response:

Noninteractive mode in Fastlane

Set the environment variable SPACESHIP_ONLY_ALLOW_INTERACTIVE_2FA to true which will only allow 2FA prompt in an interactive environment. Additionally, set FASTLANE_IS_INTERACTIVE to false to tell fastlane that you can't interact with it.

variables:
  SPACESHIP_ONLY_ALLOW_INTERACTIVE_2FA: "true"
  FASTLANE_IS_INTERACTIVE: "false"

The combination of these environment variables should cause an error to be raised instead of prompting for 2FA.

See:

Dealing with interactive prompts generically

But to answer the more generic question: 'can you exit a program if it is awaiting input'.

As far as I know, you can't generically determine if a program is reading stdin or not. However, one way to do this might be able to do this is to look at the stdout of the command for the text of the input prompt. In your case, you may look for the text Please enter the 6 digit code and bail out if it's found.

So a bash script for that might look something like this:

prompt="Please enter the 6 digit code"
program_that_might_prompt_for_input > output.txt 2>&1  &
command_pid=$!
sleep 5 # probably a more elegant way to do this
output="$(cat output.txt)"
if grep -q "$prompt" <<< "$output"; then
  echo '2FA prompt detected. bailing.' > /dev/stderr
  kill $command_pid  # if you need to
  exit 1
fi
wait # wait for command to finish
# rest of script
  • Related