Android - Building using a private Maven registry (Nexus, Artifactory, etc)

:wave: Hi folks, how are you building Capacitor Android apps in an environment with a private Maven registry (Nexus, Artifactory, etc)?

Our corporate firewall blocks access to Maven Central, google(), etc. We have an internal Artifactory registry which proxies these repos. I’m trying to get all artifacts to be downloaded from here.

Using the approach documented here, I’ve this added to my project’s settings.gradle:

dependencyResolutionManagement {
  repositoriesMode.set(RepositoriesMode.PREFER_SETTINGS)
    repositories {
      maven { url 'URL_OF_ARTIFACTORY_MAVEN_REPO' }
  }
}

This goes part of the way, but the buildscript registry declarations don’t honor this setting, such as capacitor/build.gradle at b77a9d991c461c7a0884aabc1d010a5e987f52ed · ionic-team/capacitor · GitHub

I end up getting errors that it can’t download from the public Maven Central repo. I posted to the Gradle forums but I have to imagine someone’s in a similar boat. Any thoughts?

Update: I was able to get this essentially working, but it required more work than I expected, and the use of Trapeze, using their JS API.

I wrote a Node script that replaces the buildscript section of a number of Gradle files with references to our internal repo:

  const project = new MobileProject(".", config);
  await project.load();
  await updateDependencyResolutionManagement(project);
  await setDistributionUrlAndGradleHome();
  await updateRepos(project);
  await commit(project);

And an example of how I’m using it:

const updateRepos = async (project) => {
  const pluginsBuildGradle = await project.android.getGradleFile('./capacitor-cordova-android-plugins/build.gradle');
  await updateBuildScript(pluginsBuildGradle);
  const projectBuildGradle = await project.android.getGradleFile('./build.gradle');
  await updateBuildScript(projectBuildGradle);
  const vfs = new VFS();
  const androidBuildGradle = new GradleFile('./node_modules/@capacitor/android/capacitor/build.gradle', vfs);
  await updateBuildScript(androidBuildGradle);
  await vfs.commitAll();
}

const updateBuildScript = async (pluginsBuildGradle) => {
  try {
    await pluginsBuildGradle.replaceProperties(
      {
        buildscript: {
          repositories: {
          },
        },
      },
      []
    );
  } catch (e) {
    console.log('could not replace property, sorry');
  }
  await pluginsBuildGradle.insertFragment({
    buildscript: { }
  }, `
repositories {
    maven { url 'PATH_TO_INTERNAL_JFROG_REPO'}
}
  `)
}

Note that I had to modify files even in node_modules, which required loading up a separate VFS than what the Trapeze projects loads.

Once I made all these changes, I set this up as a Capacitor hook:

  "scripts": {
    "capacitor:sync:after": "node config-android.js"
  }

It’s pretty ugly, but it seems to work. Any suggestions on cleaner approaches?

1 Like