2019-06-04 16:50:29 +00:00
{ stdenv , stdenvNoCC , lib , target-os , callPackage ,
2019-07-23 20:54:17 +00:00
mkFilter , bash , file , gnumake , watchman , gradle , androidEnvShellHook , mavenAndNpmDeps , nodejs , openjdk , jsbundle , status-go , zlib } :
2019-06-04 16:50:29 +00:00
{ build-number ? " 9 9 9 9 " ,
build-type ? " n i g h t l y " , # Build type (e.g. nightly, release, e2e). Default is to use .env.nightly file
gradle-opts ? " " ,
keystore-file ? " " , # Path to the .keystore file used to sign the package
secrets-file ? " " , # Path to the file containing secret environment variables
env ? { } # Attribute set contaning environment variables to expose to the build script
} :
let
name = " r e l e a s e - ${ target-os } " ;
gradleHome = " $ N I X _ B U I L D _ T O P / . g r a d l e " ;
localMavenRepo = " ${ mavenAndNpmDeps . deriv } / . m 2 / r e p o s i t o r y " ;
sourceProjectDir = " ${ mavenAndNpmDeps . deriv } / p r o j e c t " ;
envFileName =
if ( build-type == " r e l e a s e " || build-type == " n i g h t l y " || build-type == " e 2 e " ) then " . e n v . ${ build-type } " else
if build-type != " " then " . e n v . j e n k i n s " else " . e n v " ;
buildType' = if ( build-type == " r e l e a s e " || build-type == " n i g h t l y " ) then " r e l e a s e " else " p r " ;
generatedApkPath = " a n d r o i d / a p p / b u i l d / o u t p u t s / a p k / ${ buildType' } / a p p - ${ buildType' } . a p k " ;
outApkName = " a p p . a p k " ;
in stdenv . mkDerivation {
inherit name ;
src =
let path = ./../../../.. ;
in builtins . path { # We use builtins.path so that we can name the resulting derivation, otherwise the name would be taken from the checkout directory, which is outside of our control
inherit path ;
name = " s t a t u s - r e a c t - ${ name } - s o u r c e " ;
filter =
# Keep this filter as restrictive as possible in order to avoid unnecessary rebuilds and limit closure size
mkFilter {
dirRootsToInclude = [
" m o b i l e _ f i l e s "
" m o d u l e s / r e a c t - n a t i v e - s t a t u s "
" p a c k a g e r "
" r e s o u r c e s "
] ;
dirsToExclude = [ " . g i t " " . s v n " " C V S " " . h g " " . g r a d l e " " b u i l d " " i n t e r m e d i a t e s " " l i b s " " o b j " ] ;
2019-07-19 18:42:16 +00:00
filesToInclude = [ envFileName " s t a t u s - g o - v e r s i o n . j s o n " " V E R S I O N " ] ;
2019-06-04 16:50:29 +00:00
root = path ;
} ;
} ;
nativeBuildInputs = [ bash gradle ] ++ lib . optionals stdenv . isDarwin [ file gnumake watchman ] ;
buildInputs = [ nodejs openjdk ] ;
phases = [ " u n p a c k P h a s e " " p a t c h P h a s e " " b u i l d P h a s e " " i n s t a l l P h a s e " ] ;
postUnpack = ''
mkdir - p $ { gradleHome }
$ { if keystore-file != " " then " c p - a - - n o - p r e s e r v e = o w n e r s h i p ${ keystore-file } ${ gradleHome } / ; e x p o r t S T A T U S _ R E L E A S E _ S T O R E _ F I L E = ${ gradleHome } / $ ( b a s e n a m e ${ keystore-file } ) " else " " }
# Ensure we have the right .env file
cp - f $ sourceRoot / $ { envFileName } $ sourceRoot/.env
# Copy index.*.js input file
2019-07-23 20:54:17 +00:00
cp - a - - no-preserve = ownership $ { jsbundle } /index * . js $ sourceRoot /
2019-06-04 16:50:29 +00:00
# Copy android/ directory
cp - a - - no-preserve = ownership $ { sourceProjectDir } /android / $ sourceRoot /
chmod u + w $ sourceRoot/android
chmod u + w $ sourceRoot/android/app
chmod - R u + w $ sourceRoot/android/.gradle
mkdir $ sourceRoot/android/build && chmod - R u + w $ sourceRoot/android/build
# Copy node_modules/ directory
cp - a - - no-preserve = ownership $ { sourceProjectDir } /node_modules / $ sourceRoot /
# Make android/build directories writable under node_modules
chmod - R u + w $ sourceRoot/node_modules/react-native /
for d in ` ls $ sourceRoot/node_modules/react-native- * /android/build - d1 ` ; do
chmod - R u + w $ d
done
for d in ` ls $ sourceRoot/node_modules/react-native- * /android - d1 ` ; do
chmod u + w $ d
done
chmod u + w $ sourceRoot/node_modules/realm/android
'' ;
patchPhase = ''
prevSet = $ -
set - e
substituteInPlace android/gradlew \
- - replace ' exec gradle' " e x e c g r a d l e - S - D m a v e n . r e p o . l o c a l = ' ${ localMavenRepo } ' - - o f f l i n e ${ gradle-opts } "
substituteInPlace android/gradle.properties \
- - replace ' versionCode = 9 9 9 9 ' ' versionCode = $ { build-number } '
# OPTIONAL: There's no need to forward debug ports for a release build, just disable it
substituteInPlace node_modules/realm/android/build.gradle \
- - replace ' compileTask . dependsOn forwardDebugPort' ' compileTask'
set $ prevSet
'' ;
buildPhase =
let
inherit ( lib ) catAttrs concatStrings concatStringsSep mapAttrsToList makeLibraryPath optionalString substring toUpper ;
# Take the env attribute set and build a couple of scripts
# (one to export the environment variables, and another to unset them)
exportEnvVars = concatStringsSep " ; " ( mapAttrsToList ( name : value : " e x p o r t ${ name } = ' ${ value } ' " ) env ) ;
unsetEnvVars = concatStringsSep " ; " ( mapAttrsToList ( name : value : " u n s e t ${ name } " ) env ) ;
adhocEnvVars = optionalString stdenv . isLinux " L D _ L I B R A R Y _ P A T H = $ L D _ L I B R A R Y _ P A T H : ${ makeLibraryPath [ zlib ] } " ;
capitalizedBuildType = toUpper ( substring 0 1 buildType' ) + substring 1 ( -1 ) buildType' ;
in ''
export STATUS_REACT_HOME = $ PWD
export HOME = $ NIX_BUILD_TOP
$ { exportEnvVars }
$ { if secrets-file != " " then " s o u r c e ${ secrets-file } " else " " }
$ { androidEnvShellHook }
$ { concatStrings ( catAttrs " s h e l l H o o k " [ mavenAndNpmDeps status-go ] ) }
pushd android
$ { adhocEnvVars } gradle assemble $ { capitalizedBuildType } - S - Dmaven . repo . local = ' $ { localMavenRepo } ' - - offline $ { gradle-opts } || exit
popd > /dev/null
$ { unsetEnvVars }
'' ;
installPhase = ''
mkdir - p $ out
cp $ { generatedApkPath } $ out / $ { outApkName }
'' ;
}