jq hack #1: Expo config and Github actions

Inspired by Simon Shine, I want to showcase a use case for the tool jq. Specifically, I want to show that jq can be used for JSON substitutions.

With Expo and Expo Application Services (EAS), you can build and release mobile apps. The app stores require your submitted app to have an ever-increasing build number. You can set this property for your Expo app build within your app.json.

  "expo": {
    "ios": {
      "buildNumber": "-1"
    "android": {
      "versionCode": -1

EAS offers a setting to bump the build number but requires the runner to commit the app.json file. Another solution is to use the Github Actions workflow run number as the build number for the app, which also keeps build numbers unique across workflow runs. The ubuntu image in Github Actions ships with jq, so right before the build step in the workflow, we set


jq --arg RUN_NUMBER ${{github.run_number}} '
 .expo.ios.buildNumber = $RUN_NUMBER |
 .expo.android.versionCode = ($RUN_NUMBER | tonumber)
 ' app.json > "$TMP"

mv "$TMP" app.json

In the filter, we specify the argument RUN_NUMBER through --arg, which we then use as a value to update the nested fields through .path.to.field = $RUN_NUMBER. This approach works very well with a PR-based Expo flow in Github Actions, where we can automate builds, tag commits, and supply install links.