Skip to content

Commit

Permalink
Setup publishing for Snapshot and Stable on Maven (#34967)
Browse files Browse the repository at this point in the history
Summary:
Pull Request resolved: #34967

This diff is a preparatory work for publishing artifacts on Maven Central.
What it does is:
1. It sets up all the 3 modules (react-native, hermes-engine, external-artifacts) for publishg
2. Adds coordinates to publish on the Snapshot repository
3. Adds support for appendign -SNAPSHOT version if invoked with `-PisNightly=true`
4. Configures GPG signing of artifacts.

I haven't touched the CircleCI and JS code yet. I'll do it in another diff.

Changelog:
[General] [Changed] - Setup publishing for Snapshot and Stable on Maven

Reviewed By: mdvacca, cipolleschi

Differential Revision: D40146212

fbshipit-source-id: 9321e16f6c18b35bc3ae785749d613085c56e7bc
  • Loading branch information
cortinico authored and facebook-github-bot committed Oct 13, 2022
1 parent 2934399 commit 0e2f090
Show file tree
Hide file tree
Showing 8 changed files with 198 additions and 91 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ project.xcworkspace
/ReactAndroid/gradle/
/ReactAndroid/gradlew
/ReactAndroid/gradlew.bat
/ReactAndroid/external-artifacts/build/
/ReactAndroid/external-artifacts/artifacts/
/ReactAndroid/hermes-engine/build/
/ReactAndroid/hermes-engine/.cxx/
/template/android/app/build/
Expand Down
81 changes: 22 additions & 59 deletions ReactAndroid/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@ buildscript {
plugins {
id("com.android.library")
id("com.facebook.react")
id("maven-publish")
id("de.undercouch.download")
id("maven-publish")
}

import com.facebook.react.tasks.internal.*
Expand All @@ -26,10 +26,10 @@ import java.nio.file.Paths
import kotlin.Pair

import de.undercouch.gradle.tasks.download.Download
import org.apache.tools.ant.taskdefs.condition.Os
import org.apache.tools.ant.filters.ReplaceTokens

def AAR_OUTPUT_URL = "file://${projectDir}/../android"
version = VERSION_NAME
group = "com.facebook.react"

// We download various C++ open-source dependencies into downloads.
// We then copy both the downloaded code and our custom makefiles and headers into third-party-ndk.
// After that we build native code from src/main/jni with module path pointing at third-party-ndk.
Expand Down Expand Up @@ -349,7 +349,7 @@ def reactNativeArchitectures() {
return value ? value.split(",") : ["armeabi-v7a", "x86", "x86_64", "arm64-v8a"]
}

tasks.register("packageReactNdkLibsForBuck") {
task packageReactNdkLibsForBuck(type: Copy) {
dependsOn("mergeDebugNativeLibs")
// Shared libraries (.so) are copied from the merged_native_libs folder instead
from("$buildDir/intermediates/merged_native_libs/debug/out/lib/")
Expand Down Expand Up @@ -396,11 +396,11 @@ android {
externalNativeBuild {
cmake {
arguments "-DREACT_COMMON_DIR=${reactNativeRootDir}/ReactCommon",
"-DREACT_ANDROID_DIR=$projectDir",
"-DREACT_BUILD_DIR=$buildDir",
"-DANDROID_STL=c++_shared",
"-DANDROID_TOOLCHAIN=clang",
"-DANDROID_PLATFORM=android-21"
"-DREACT_ANDROID_DIR=$projectDir",
"-DREACT_BUILD_DIR=$buildDir",
"-DANDROID_STL=c++_shared",
"-DANDROID_TOOLCHAIN=clang",
"-DANDROID_PLATFORM=android-21"

targets "reactnativejni",
"jscexecutor",
Expand Down Expand Up @@ -430,7 +430,7 @@ android {
}
}
ndk {
abiFilters (*reactNativeArchitectures())
abiFilters(*reactNativeArchitectures())
}
}

Expand Down Expand Up @@ -554,7 +554,7 @@ android {
publishing {
multipleVariants {
withSourcesJar()
allVariants()
includeBuildTypeValues('debug', 'release')
}
}
}
Expand Down Expand Up @@ -611,54 +611,17 @@ react {
codegenDir = file(findNodeModulePath(projectDir, "react-native-codegen") ?: "../packages/react-native-codegen/")
}

afterEvaluate {
publishing {
publications {
release(MavenPublication) {
// We do a multi variant release
from components.default

// You can then customize attributes of the publication as shown below.
artifactId = POM_ARTIFACT_ID
groupId = GROUP
version = VERSION_NAME

pom {
name = POM_NAME
description = "A framework for building native apps with React"
url = "https://github.com/facebook/react-native"

developers {
developer {
id = "facebook"
name = "Facebook"
}
}

licenses {
license {
name = "MIT License"
url = "https://github.com/facebook/react-native/blob/HEAD/LICENSE"
distribution = "repo"
}
}

scm {
url = "https://github.com/facebook/react-native.git"
connection = "scm:git:https://github.com/facebook/react-native.git"
developerConnection = "scm:git:git@github.com:facebook/react-native.git"
}
}
}
}
apply plugin: "org.jetbrains.kotlin.android"

repositories {
maven {
name = "npm"
url = AAR_OUTPUT_URL
}
/* Publishing Configuration */
apply from: "./publish.gradle"

// We need to override the artifact ID as this project is called `ReactAndroid` but
// the maven coordinates are on `react-native`.
publishing {
publications {
getByName("release") {
artifactId 'react-native'
}
}
}

apply plugin: "org.jetbrains.kotlin.android"
32 changes: 32 additions & 0 deletions ReactAndroid/external-artifacts/build.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/

plugins {
id("maven-publish")
}

group = "com.facebook.react"
version = parent.publishing_version
configurations.maybeCreate("default")

// The artifact should be placed inside the `artifacts/hermes-ios.tar.gz` location.
def hermesiOSArtifactFile = layout.projectDirectory.file('artifacts/hermes-ios.tar.gz')
def hermesiOSArtifact = artifacts.add('default', hermesiOSArtifactFile) {
type 'tgz'
extension 'tar.gz'
classifier 'hermes-ios'
}

apply from: "../publish.gradle"

publishing {
publications {
getByName("release") {
artifact hermesiOSArtifact
}
}
}
4 changes: 0 additions & 4 deletions ReactAndroid/gradle.properties
Original file line number Diff line number Diff line change
@@ -1,10 +1,6 @@
VERSION_NAME=1000.0.0
GROUP=com.facebook.react

POM_NAME=ReactNative
POM_ARTIFACT_ID=react-native
POM_PACKAGING=aar

# JVM Versions
ANDROIDX_APPCOMPAT_VERSION=1.4.1
ANDROIDX_AUTOFILL_VERSION=1.1.0
Expand Down
31 changes: 4 additions & 27 deletions ReactAndroid/hermes-engine/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ plugins {
id("de.undercouch.download")
id("com.android.library")
id("maven-publish")
id("signing")
}

group = "com.facebook.react"
Expand Down Expand Up @@ -56,10 +57,6 @@ def skipPrefabPublishing = System.getenv("REACT_NATIVE_HERMES_SKIP_PREFAB") != n
// We inject the JSI directory used inside the Hermes build with the -DJSI_DIR config.
def jsiDir = new File(reactNativeRootDir, "ReactCommon/jsi")

// The .aar is placed inside the ./android folder at the top level.
// There it will be placed alongside the React Android .aar
def AAR_OUTPUT_URL = "file://${rootDir}/android"

task downloadHermes(type: Download) {
src("https://github.com/facebook/hermes/tarball/${hermesVersion}")
onlyIfNewer(true)
Expand Down Expand Up @@ -234,27 +231,7 @@ afterEvaluate {
}
preBuild.dependsOn(buildHermes)
preBuild.dependsOn(prepareHeadersForPrefab)
// Needed as some of the native sources needs to be downloaded
// before configureCMakeRelease/configureCMakeMinSizeRel could be executed.
reactNativeArchitectures().each { architecture ->
tasks.findByName("configureCMakeMinSizeRel[${architecture}]")?.configure { dependsOn(preBuild) }
tasks.findByName("configureCMakeRelease[${architecture}]")?.configure { dependsOn(preBuild) }
}
configureCMakeRelease.dependsOn(preBuild)
configureCMakeMinSizeRel.dependsOn(preBuild)

publishing {
publications {
release(MavenPublication) {
from components.default
artifactId = "hermes-engine"
}
}
repositories {
maven {
name = "npm"
url = AAR_OUTPUT_URL
}
}
}
prepareHeadersForPrefab.dependsOn(buildHermes)
}

apply from: "../publish.gradle"
102 changes: 102 additions & 0 deletions ReactAndroid/publish.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/

apply plugin: 'maven-publish'
apply plugin: 'signing'

def isNightly = findProperty("isNightly")?.toBoolean()
def sonatypeUsername = findProperty("SONATYPE_USERNAME")
def sonatypePassword = findProperty("SONATYPE_PASSWORD")
def signingKey = findProperty("SIGNING_KEY")
def signingPwd = findProperty("SIGNING_PWD")

def reactAndroidProjectDir = project(':ReactAndroid').projectDir
def androidOutputUrl = "file://${reactAndroidProjectDir}/../android"

publishing {
publications {
release(MavenPublication) {
afterEvaluate {
// We do a multi variant release, so for Android libraries
// we publish `components.release`
if (plugins.hasPlugin("com.android.library")) {
from components.default
}
}

// We populate the publishing version using the project version,
// appending -SNAPSHOT if on nightly.
if (isNightly) {
version = this.version + "-SNAPSHOT"
} else {
version = this.version
}

pom {
name = "react-native"
description = "A framework for building native apps with React"
url = "https://github.com/facebook/react-native"

developers {
developer {
id = "facebook"
name = "Facebook"
}
}

licenses {
license {
name = "MIT License"
url = "https://github.com/facebook/react-native/blob/HEAD/LICENSE"
distribution = "repo"
}
}

scm {
url = "https://github.com/facebook/react-native.git"
connection = "scm:git:https://github.com/facebook/react-native.git"
developerConnection = "scm:git:git@github.com:facebook/react-native.git"
}
}
}
}

repositories {
maven {
name = "npm"
url = androidOutputUrl
}
if (sonatypeUsername && sonatypePassword) {
maven {
name = "mavenCentral"
url = "https://oss.sonatype.org/service/local/staging/deploy/maven2/"
credentials {
username = sonatypeUsername
password = sonatypePassword
}
}
maven {
name = "mavenSnapshots"
url = "https://oss.sonatype.org/content/repositories/snapshots/"
credentials {
username = sonatypeUsername
password = sonatypePassword
}
}
}
}

if (signingKey && signingPwd) {
logger.info("PGP Key found - Signing enabled")
signing {
useInMemoryPgpKeys(signingKey, signingPwd)
sign(publishing.publications.release)
}
} else {
logger.info("Signing disabled as the PGP key was not found")
}
}
31 changes: 31 additions & 0 deletions build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -74,3 +74,34 @@ tasks.register("downloadAll") {
dependsOn(":ReactAndroid:hermes-engine:dependencies")
dependsOn(":ReactAndroid:hermes-engine:androidDependencies")
}

tasks.register("publishAllInsideNpmPackage") {
description =
"Publish all the artifacts to be available inside the NPM package in the `android` folder."
// Due to size constraints of NPM, we publish only react-native and hermes-engine inside
// the NPM package.
dependsOn(":ReactAndroid:installArchives")
dependsOn(":ReactAndroid:hermes-engine:installArchives")
}

tasks.register("publishAllToMavenLocal") {
description = "Publish all the artifacts to be available inside Maven Local."
dependsOn(":ReactAndroid:publishToMavenLocal")
dependsOn(":ReactAndroid:external-artifacts:publishToMavenLocal")
dependsOn(":ReactAndroid:hermes-engine:publishToMavenLocal")
}

tasks.register("publishAllToMavenSnapshots") {
description =
"Publish all the artifacts as a snapshot (used for testing/nightly) on Maven Central."
dependsOn(":ReactAndroid:publishAllPublicationsToMavenSnapshotsRepository")
dependsOn(":ReactAndroid:external-artifacts:publishAllPublicationsToMavenSnapshotsRepository")
dependsOn(":ReactAndroid:hermes-engine:publishAllPublicationsToMavenSnapshotsRepository")
}

tasks.register("publishAllToMavenCentral") {
description = "Publish all the artifacts as a release on Maven Central."
dependsOn(":ReactAndroid:publishAllPublicationsToMavenCentralRepository")
dependsOn(":ReactAndroid:external-artifacts:publishAllPublicationsToMavenCentralRepository")
dependsOn(":ReactAndroid:hermes-engine:publishAllPublicationsToMavenCentralRepository")
}
6 changes: 5 additions & 1 deletion settings.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,11 @@ pluginManagement {
}
}

include(":ReactAndroid", ":ReactAndroid:hermes-engine", ":packages:rn-tester:android:app")
include(
":ReactAndroid",
":ReactAndroid:hermes-engine",
":ReactAndroid:external-artifacts",
":packages:rn-tester:android:app")

// Include this to enable codegen Gradle plugin.
includeBuild("packages/react-native-gradle-plugin/")
Expand Down

0 comments on commit 0e2f090

Please sign in to comment.