Hosted OTA updates with EAS Builds

Is it possible to use custom hosted OTA updates with EAS Builds? With Expo CLI, you can use the --public-url argument to specify the source of OTA updates. How can this be done?

Hey @safarishare,

If you’re building a Bare (generic) project via EAS build then it is possible. You can find the docs for handling updates here. The build process no longer performs a publish so there’s no longer a need for the --public-url argument.

If you’re building a Managed project via EAS, it’s not supported yet.

Cheers,
Adam

Hey @adamjnav thanks for your response. Where can I track progress on this work?

it’s technically possible to do this if you write a config plugin to modify Expo.plist / AndroidManifest.xml to point to the self hosting url.

we’re adding updates.url to app.json config and hope to have something ready for sdk 42. you can watch pull requests to expo-cli if you want to see it as it happens

1 Like

@notbrent please confirm if the config plugin can be used with a managed project

yes, on eas build. that is how everything works on eas build :slight_smile: every field in your app.json is applied with a config plugin

@notbrent this is awesome! Can’t wait to see what else is possible with these config plugins.

Here is my solution incase anybody needs this. Looking forward to the next Expo update

// app.config.json
{
  "plugins": ["./hosted-ota-plugin.js"]
}

// ./hosted-ota-plugin.js
require("dotenv").config();

const {
  withExpoPlist,
  withAndroidManifest,
  AndroidConfig,
} = require("@expo/config-plugins");

const {
  addMetaDataItemToMainApplication,
  getMainApplicationOrThrow,
} = AndroidConfig.Manifest;

const updateUrl = process.env.UPDATE_URL;

const ANDROID_UPDATE_URL = "expo.modules.updates.EXPO_UPDATE_URL";
const IOS_UPDATE_URL = "EXUpdatesURL";

module.exports = function (config) {
  if (!updateUrl) return config;

  const androidUrl = `${url}/android-index.json`;
  const iosUrl = `${url}/ios-index.json`;

  return withPlugins(config, [
    [withUpdatesAndroid, androidUrl],
    [withUpdatesIOS, iosUrl],
  ]);
};

function withUpdatesAndroid(config, url) {
  return withAndroidManifest(config, (props) => {
    const mainApplication = getMainApplicationOrThrow(props.modResults);

    addMetaDataItemToMainApplication(mainApplication, ANDROID_UPDATE_URL, url);

    return props;
  });
}

function withUpdatesIOS(config, url) {
  return withExpoPlist(config, (props) => {
    props.modResults[IOS_UPDATE_URL] = url;

    return props;
  });
}
3 Likes