1

I'm trying to automate a post-build process to get closer to a one-click release. However, I'm having problems with a script that.

Expected: The script to work exactly like the command line.

Results: Everything works, including grabbing the versionCodes except I am getting a curl: (26) Failed to open/read local data from file/application

The script I wanted to imitate with a more automated approach.

    react-native bundle \
   --platform android \
   --dev false \
   --entry-file index.js \
   --bundle-output android-release.bundle \
   --sourcemap-output android-release.bundle.map &&

curl https://upload.bugsnag.com/react-native-source-map \
  -F apiKey=API-KEY \
  -F appVersion=10.6.7 \
  -F appVersionCode=4515 \
  -F dev=false \
  -F platform=android \
  -F sourceMap=@android-release.bundle.map \
  -F bundle=@android-release.bundle 

react-native bundle \
   --platform ios \
   --dev false \
   --entry-file index.js \
   --bundle-output ios-release.bundle \
   --sourcemap-output ios-release.bundle.map &&

curl https://upload.bugsnag.com/react-native-source-map \
-F apiKey=API-KEY \
  -F appVersion=10.6.7 \
  -F appBundleVersion=4515 \
  -F dev=false \
  -F platform=ios \
  -F sourceMap=@ios-release.bundle.map \
  -F bundle=@ios-release.bundle 

So I wrote a script to fix this, which is

#!/bin/sh

# Ensure this is run on the commit used to generate the published app!

# Comment this line out to enable bundling and publishing
# debug=echo

bundle () {
  platform=$1

  $debug yarn react-native bundle \
    --platform "$platform" \
    --dev false \
    --entry-file index.js \
    --bundle-output "$platform-release.bundle" \
    --sourcemap-output "$platform-release.bundle.map"
}

upload () {
  platform=$1
  version=$2
  version_code=$3

  # See https://docs.bugsnag.com/api/rn-source-map-upload/#uploading-source-maps
  
  
  curl --http1.1 https://upload.bugsnag.com/react-native-source-map \
    -F apiKey="$BUGSNAG_API_KEY" \
    -F appVersion="$version" \
    -F appVersionCode="$version_code" \
    -F dev=false \
    -F platform="$platform" \
    -F sourceMap=@"$platform-release-bundle.map" \
    -F bundle=@"$platform-release.bundle" \
 
}

read_version () {
  local tag=$1
  local file=$2
  echo "$(grep -m 1 $tag $file | grep -o '[0-9]\+\(\.[0-9]\+\)*')"
}

BUGSNAG_API_KEY=$(plutil -p ios/RVLife/Info.plist | grep BugsnagAPIKey | awk '{ print $3 }' | sed 's/"//g')
if [[ -z $BUGSNAG_API_KEY ]]; then
  echo "Couldn't find bugsnag API key" 
  exit 1
fi

IOS_VERSION=$(read_version MARKETING_VERSION ios/RVLife.xcodeproj/project.pbxproj)
echo "iOS app version:      $IOS_VERSION" 

IOS_VERSION_CODE=$(read_version CURRENT_PROJECT_VERSION ios/RVLife.xcodeproj/project.pbxproj)
echo "iOS version code:     $IOS_VERSION_CODE" 

if [[ -z $IOS_VERSION || -z $IOS_VERSION_CODE ]]; then
  echo "Couldn't get iOS app versions" 
  exit 1
fi

bundle ios
upload ios "$IOS_VERSION" "$IOS_VERSION_CODE"

echo "" 

ANDROID_VERSION=$(read_version versionName android/app/build.gradle)
echo "Android app version:  $ANDROID_VERSION" 

ANDROID_VERSION_CODE=$(read_version versionCode android/app/build.gradle)
echo "Android version code: $ANDROID_VERSION_CODE" 

if [[ -z $ANDROID_VERSION || -z $ANDROID_VERSION_CODE ]]; then
  echo "Couldn't get Android app versions" 
  exit 1
fi

bundle android
upload android "$ANDROID_VERSION" "$ANDROID_VERSION_CODE"

I'm assuming I messed up some syntax or permissions or something somewhere, but can't seem to find the area I did. Any help is appreciated.

Difference between bash -x myScript and set -x on command line

Command Line

omz_termsupport_preexec:1> [[ '' == true ]]
+omz_termsupport_preexec:3> emulate -L zsh
+omz_termsupport_preexec:4> setopt extended_glob
+omz_termsupport_preexec:7> local -a cmdargs
+omz_termsupport_preexec:8> cmdargs=( curl https://upload.bugsnag.com/react-native-source-map -F -F -F -F -F - ) 
+omz_termsupport_preexec:10> [[ curl = fg ]]
+omz_termsupport_preexec:44> local CMD=curl
+omz_termsupport_preexec:45> local LINE='curl https://upload.bugsnag.com/react-native-source-map -F  -F  -F  -F  -F  -'
+omz_termsupport_preexec:47> title '$CMD' '%100>...>$LINE%<<'
+title:1> emulate -L zsh
+title:2> setopt prompt_subst
+title:4> [[ '' == *term* ]]
+title:8> : '%100>...>$LINE%<<'
+title:10> case xterm-256color (cygwin | xterm*)
+title:12> print -Pn '\e]2;%100\>...\>\$LINE%\<\<\a'
+title:13> print -Pn '\e]1;\$CMD\a'
+-zsh:75> curl https://upload.bugsnag.com/react-native-source-map -F 'apiKey=API-KEY' -F 'appVersion=10.6.7’ -F 'appBundleVersion=4515' -F 'dev=false' -F 'platform=ios' -F 'sourceMap=@ios-release.bundle.map' -F 'bundle=@ios-release.bundle'
OK%  

SH Script

+ upload ios 10.6.7 4515
+ platform=ios
+ version=10.6.7
+ version_code=4515
+ curl --http1.1 https://upload.bugsnag.com/react-native-source-map -F apiKey=API-KEY -F appVersion=10.6.7 -F appVersionCode=4515 -F dev=false -F platform=ios -F sourceMap=@ios-release-bundle.map -F bundle=@ios-release.bundle
curl: (26) Failed to open/read local data from file/application
+ echo ''
Kurt Anderson
  • 134
  • 1
  • 10
  • 2
    Please paste your script first at [shellcheck.net](http://www.shellcheck.net/) and try to implement the recommendations made there. – Cyrus Aug 26 '20 at 16:59
  • Are you using [`sh` or `bash`](https://stackoverflow.com/questions/5725296/difference-between-sh-and-bash)? – 0stone0 Aug 26 '20 at 16:59
  • `sh` ([Bourne-shell](https://en.wikipedia.org/wiki/Bourne_shell)) is usally not `bash` ([Bourne-again shell](https://en.wikipedia.org/wiki/Bash_(Unix_shell))). – Cyrus Aug 26 '20 at 16:59
  • You're right this is a shell (.sh) script! – Kurt Anderson Aug 26 '20 at 17:16
  • @Cyrus, ...though `sh` is usually POSIX sh and not Bourne, these days. – Charles Duffy Aug 26 '20 at 17:20
  • @KurtAnderson, run `bash -x yourscript`, and compare the traces it emits to those you get when running the same commands in an interactive shell after running `set -x`. – Charles Duffy Aug 26 '20 at 17:21
  • @KurtAnderson, that said, `function` isn't guaranteed to work with `sh` at all. Use `funcname() {`, not `function funcname {` or `function funcname() {`; and see the relevant entries in the tables at http://wiki.bash-hackers.org/scripting/obsolete – Charles Duffy Aug 26 '20 at 17:22
  • ...since what you're getting is specifically a curl error, though, what we really need is to compare the `set -x` logs for the specific curl command that fails. – Charles Duffy Aug 26 '20 at 17:24
  • BTW, `echo` is not a great tool to use for debugging. For example, there's no way to tell the difference between `echo ./mycommand "first argument"` and `echo ./mycommand "first" "argument"`. `set -x` is much more powerful, though you can also write your own equivalent command. f/e, `printCmd() { printf '%q ' "$@" >&2; echo >&2; }` would let you set `debug=printCmd` and get a more `set -x`-like trace. (That'll also show bugs caused by hidden characters like DOS newlines). – Charles Duffy Aug 26 '20 at 17:38
  • Okay, put those logs up there and updated to fix all the function calls as well as double quote things. Still an error. It looks like the successful call uses single quotes around the -F parameters, would that be important? – Kurt Anderson Aug 26 '20 at 17:39
  • There are several interesting details in the quoting from that trace. There are some `’` quotes where they should be `'` to be syntactically valid; and if bash adds quotes to a `set -x` trace, it's generally doing that for an important reason (f/e, to represent that the content of that quoted string is being passed literally rather than treated as shell syntax). – Charles Duffy Aug 26 '20 at 17:41
  • BTW, it looks like your interactive shell is zsh? zsh isn't POSIX-compatible except when explicitly put into a compatibility mode, so it's not a great place to test syntax you're going to use in scripts later running with sh or bash. – Charles Duffy Aug 26 '20 at 17:42
  • ...adding quotes around a string with an `=` in it is probably just a zsh-vs-bash thing and not very important; by contrast, adding quotes around a _space_ is very important; what's surprising to me is that the quoting looks more correct in the script version than the command-line version (at least on account of there being a `’` where one would expect a `'` in your trace from the manual invocation). – Charles Duffy Aug 26 '20 at 17:44
  • BTW, the error message is specifically saying that curl can't find either the file `ios-release.bundle` or the file `ios-release-bundle.map` in the current working directory. One place to look at is what the working directory _is_ when that error is thrown, and whether the files are actually present. – Charles Duffy Aug 26 '20 at 17:46
  • Just switched back to normal bash. Still the same bug. Hmm, had it print the current working directory, and it's where I expect it to be. I guess curl could be executing in a different place by default. Let me look into that. – Kurt Anderson Aug 26 '20 at 17:50
  • Could also put a fully-qualified path onto the command line; if it's `-F sourceMap=@/exact/path/to/ios-release.bundle.map`, that rules out any potential current-working-directory issues. – Charles Duffy Aug 26 '20 at 18:27
  • ...honestly, if you're still having problems at that point, the next step I'd probably use is to use `strace` (or similar tools as appropriate to your OS) to trace curl's operation, to see exactly which operation it's running fails, whether that's an `open()` of an input file (as currently expected), or something else.. – Charles Duffy Aug 26 '20 at 18:30
  • The curl command on the command line is different from the one in the script. Can you make them the same ? – Philippe Aug 26 '20 at 21:46
  • Got the Same issue today @KurtAnderson, did you figure it out? – Walter Martin Vargas-Pena Sep 02 '20 at 04:55
  • I wonder if this has something to do with it https://docs.fastlane.tools/advanced/fastlane/#directory-behavior @KurtAnderson – Walter Martin Vargas-Pena Sep 02 '20 at 14:02

0 Answers0