Skip to content

Commit

Permalink
fix release script
Browse files Browse the repository at this point in the history
  • Loading branch information
cassandracomar committed Apr 23, 2023
1 parent 323e8c2 commit e12bf68
Showing 1 changed file with 102 additions and 75 deletions.
177 changes: 102 additions & 75 deletions modules/release.nix
Original file line number Diff line number Diff line change
Expand Up @@ -8,32 +8,46 @@ let

otaTools = config.build.otaTools;

wrapScript = { commands, keysDir }: let
jre = if (config.androidVersion >= 11) then pkgs.jdk11_headless else pkgs.jre8_headless;
deps = with pkgs;
[ otaTools openssl jre zip unzip pkgs.getopt which toybox vboot_reference utillinux
python3 # ota_from_target_files invokes, brillo_update_payload which has "truncate_file" which invokes python
];
in config.build.signing.withKeys keysDir ''
export PATH=${lib.makeBinPath deps}:$PATH
export EXT2FS_NO_MTAB_OK=yes
${commands}
'';
wrapScript = { commands, keysDir }:
let
jre = if (config.androidVersion >= 11) then pkgs.jdk11_headless else pkgs.jre8_headless;
deps = with pkgs;
[
otaTools
openssl
jre
zip
unzip
pkgs.getopt
which
toybox
vboot_reference
utillinux
python3 # ota_from_target_files invokes, brillo_update_payload which has "truncate_file" which invokes python
];
in
config.build.signing.withKeys keysDir ''
export PATH=${lib.makeBinPath deps}:$PATH
export EXT2FS_NO_MTAB_OK=yes
${commands}
'';

runWrappedCommand = name: script: args: pkgs.runCommand "${config.device}-${name}-${config.buildNumber}.zip" {
nativeBuildInputs = with pkgs; [ sops age gnupg config.build.checkTargetFiles ];
} (wrapScript {
commands = script (args // {out="$out";});
keysDir = config.signing.keyStorePath;
});
runWrappedCommand = name: script: args: pkgs.runCommand "${config.device}-${name}-${config.buildNumber}.zip"
{
nativeBuildInputs = with pkgs; [ sops age gnupg config.build.checkTargetFiles ];
}
(wrapScript {
commands = script (args // { out = "$out"; });
keysDir = config.signing.keyStorePath;
});

fileSigningEnvironment = name: script: args: config.build.mkAndroid {
name = "${config.device}-${name}-${config.buildNumber}.zip";
outputs = ["out"];
outputs = [ "out" ];
nativeBuildInputs = with pkgs; [ sops age gnupg config.build.checkTargetFiles ];
buildPhase = wrapScript {
commands = script (args // {out="$out";});
commands = script (args // { out = "$out"; });
keysDir = config.signing.keyStorePath;
};

Expand All @@ -54,24 +68,24 @@ let
'';
imgScript = { targetFiles, out }: ''img_from_target_files ${targetFiles} ${out}'';
factoryImgScript = { targetFiles, img, out }: ''
ln -s ${targetFiles} ${config.device}-target_files-${config.buildNumber}.zip
${pkgs.coreutils}/bin/cp -rL --copy-contents ${img} ${config.device}-img-${config.buildNumber}.zip
export DEVICE=${config.device}
export PRODUCT=${config.device}
export BUILD=${config.buildNumber}
export VERSION=${lib.toLower config.buildNumber}
get_radio_image() {
${lib.getBin pkgs.libarchive}/bin/bsdtar xvf ${targetFiles} -O OTA/android-info.txt \
| grep "require version-$1" | cut -d'=' -f2 | tr '[:upper:]' '[:lower:]' || exit 1
}
export BOOTLOADER=$(get_radio_image bootloader)
export RADIO=$(get_radio_image baseband)
export PATH=${lib.getBin pkgs.zip}/bin:${lib.getBin pkgs.unzip}/bin:$PATH
${pkgs.runtimeShell} ${config.source.dirs."device/common".src}/generate-factory-images-common.sh
${pkgs.coreutils}/bin/cp -rL --copy-contents ${config.device}-factory-${config.buildNumber}.zip ${out}
ln -s ${targetFiles} ${config.device}-target_files-${config.buildNumber}.zip || true
${pkgs.coreutils}/bin/cp -rL --copy-contents ${img} ${config.device}-img-${config.buildNumber}.zip || true
export DEVICE=${config.device}
export PRODUCT=${config.device}
export BUILD=${config.buildNumber}
export VERSION=${lib.toLower config.buildNumber}
get_radio_image() {
${lib.getBin pkgs.libarchive}/bin/bsdtar xvf ${targetFiles} -O OTA/android-info.txt \
| grep "require version-$1" | cut -d'=' -f2 | tr '[:upper:]' '[:lower:]' || exit 1
}
export BOOTLOADER=$(get_radio_image bootloader)
export RADIO=$(get_radio_image baseband)
export PATH=${lib.getBin pkgs.zip}/bin:${lib.getBin pkgs.unzip}/bin:$PATH
${pkgs.runtimeShell} ${config.source.dirs."device/common".src}/generate-factory-images-common.sh
${pkgs.coreutils}/bin/cp -rL --copy-contents ${config.device}-factory-${config.buildNumber}.zip ${out} || true
'';
in
{
Expand All @@ -98,7 +112,7 @@ in
};

otaArgs = mkOption {
default = [];
default = [ ];
type = types.listOf types.str;
internal = true;
};
Expand All @@ -110,9 +124,11 @@ in
};

config = {
prevBuildNumber = let
prevBuildNumber =
let
metadata = builtins.readFile (config.prevBuildDir + "/${config.device}-${config.channel}");
in mkDefault (lib.head (lib.splitString " " metadata));
in
mkDefault (lib.head (lib.splitString " " metadata));
prevTargetFiles = mkDefault (config.prevBuildDir + "/${config.device}-target_files-${config.prevBuildNumber}.zip");

otaArgs =
Expand All @@ -123,7 +139,7 @@ in
config.build = rec {
# These can be used to build these products inside nix. Requires putting the secret keys under /keys in the sandbox
unsignedTargetFiles = config.build.android + "/${config.productName}-target_files-${config.buildNumber}.zip";
signedTargetFiles = fileSigningEnvironment "signed_target_files" signedTargetFilesScript { targetFiles=unsignedTargetFiles;};
signedTargetFiles = fileSigningEnvironment "signed_target_files" signedTargetFilesScript { targetFiles = unsignedTargetFiles; };
targetFiles = if config.signing.enable then signedTargetFiles else unsignedTargetFiles;
ota = runWrappedCommand "ota_update" otaScript { inherit targetFiles; };
incrementalOta = runWrappedCommand "incremental-${config.prevBuildNumber}" otaScript { inherit targetFiles; inherit (config) prevTargetFiles; };
Expand All @@ -132,13 +148,20 @@ in
unpackedImg = pkgs.robotnix.unpackImg config.build.img;

# Pull this out of target files, because (at least) verity key gets put into boot ramdisk
bootImg = pkgs.runCommand "boot.img" {} "${pkgs.unzip}/bin/unzip -p ${targetFiles} IMAGES/boot.img > $out";
recoveryImg = pkgs.runCommand "recovery.img" {} "${pkgs.unzip}/bin/unzip -p ${targetFiles} IMAGES/recovery.img > $out";
bootImg = pkgs.runCommand "boot.img" { } "${pkgs.unzip}/bin/unzip -p ${targetFiles} IMAGES/boot.img > $out";
recoveryImg = pkgs.runCommand "recovery.img" { } "${pkgs.unzip}/bin/unzip -p ${targetFiles} IMAGES/recovery.img > $out";

# BUILDID_PLACEHOLDER below was originally config.apv.buildID, but we don't want to have to depend on setting a buildID generally.
otaMetadata = (rec {
grapheneos = pkgs.writeText "${config.device}-${config.channel}" ''
${config.buildNumber} ${toString config.buildDateTime} BUILDID_PLACEHOLDER ${config.channel}
${config.buildNumber} ${toString config.buildDateTime} ${
if config.apv.enable
then config.apv.buildID
else
if config.adevtool.enable
then config.adevtool.buildID
else "BUILDID_PLACEHOLDER"
} ${config.channel}
'';
lineageos = pkgs.writeText "lineageos-${config.device}.json" (
# https://github.com/LineageOS/android_packages_apps_Updater#server-requirements
Expand Down Expand Up @@ -168,7 +191,7 @@ in
}.${config.apps.updater.flavor};

# TODO: target-files aren't necessary to publish--but are useful to include if prevBuildDir is set to otaDir output
otaDir = pkgs.runCommand "${config.device}-otaDir" {} ''
otaDir = pkgs.runCommand "${config.device}-otaDir" { } ''
mkdir -p $out
ln -s "${ota}" "$out/${ota.name}"
ln -s "${targetFiles}" "$out/${config.device}-target_files-${config.buildNumber}.zip"
Expand All @@ -180,34 +203,38 @@ in
# TODO: Do this in a temporary directory. It's ugly to make build dir and ./tmp/* dir gets cleared in these scripts too.
releaseScript =
(if (!config.signing.enable) then lib.warn "releaseScript should be used only if signing.enable = true; Otherwise, the build might be using incorrect keys / certificate metadata" else lib.id)
pkgs.writeShellScript "release.sh" ( ''
set -euo pipefail
if [[ $# -ge 1 ]]; then
PREV_BUILDNUMBER="$1"
else
PREV_BUILDNUMBER=""
fi
'' + (wrapScript { keysDir=config.signing.keyStorePath; commands=''
echo Signing target files
${signedTargetFilesScript { targetFiles=unsignedTargetFiles; out=signedTargetFiles.name; }}
echo Building OTA zip
${otaScript { targetFiles=signedTargetFiles.name; out=ota.name; }}
if [[ ! -z "$PREV_BUILDNUMBER" ]]; then
echo Building incremental OTA zip
${otaScript {
targetFiles=signedTargetFiles.name;
prevTargetFiles="${config.device}-target_files-$PREV_BUILDNUMBER.zip";
out="${config.device}-incremental-$PREV_BUILDNUMBER-${config.buildNumber}.zip";
}}
fi
echo Building .img file
${imgScript { targetFiles=signedTargetFiles.name; out=img.name; }}
echo Building factory image
${factoryImgScript { targetFiles=signedTargetFiles.name; img=img.name; out=factoryImg.name; }}
'' + lib.optionalString config.apps.updater.enable ''
echo Writing updater metadata
${writeOtaMetadata { otaFile=ota.name; path = "."; }}
''; }));
pkgs.writeShellScript "release.sh"
(''
set -eo pipefail
if [[ $# -ge 1 ]]; then
PREV_BUILDNUMBER="$1"
else
PREV_BUILDNUMBER=""
fi
'' + (wrapScript {
keysDir = config.signing.keyStorePath;
commands = ''
echo Signing target files
${pkgs.coreutils}/bin/cp -rL --copy-contents ${signedTargetFiles} ${signedTargetFiles.name}
echo Building OTA zip
${otaScript { targetFiles=signedTargetFiles.name; out=ota.name; }}
if [[ ! -z "$PREV_BUILDNUMBER" ]] && [[ ${if builtins.toString config.incremental == "true" then "true" else "false"} == "true" ]]; then
echo Building incremental OTA zip
${otaScript {
targetFiles=signedTargetFiles.name;
prevTargetFiles="${config.device}-target_files-$PREV_BUILDNUMBER.zip";
out="${config.device}-incremental-$PREV_BUILDNUMBER-${config.buildNumber}.zip";
}}
fi
echo Building .img file
${imgScript { targetFiles=signedTargetFiles.name; out=img.name; }}
echo Building factory image
${factoryImgScript { targetFiles=signedTargetFiles.name; img=img.name; out=factoryImg.name; }}
'' + lib.optionalString config.apps.updater.enable ''
echo Writing updater metadata
${writeOtaMetadata { otaFile=ota.name; path = "."; }}
'';
}));
};
}

0 comments on commit e12bf68

Please sign in to comment.