forked from Qortal/qortal
Reworked/improved auto-update build/publish tools.
Instead of working on a single 'auto-update' branch, that needed to be rebased from master branch's HEAD, we create an orphan branch named after master:HEAD containing on the update file. This allows us to keep/delete updates on a per-commit basis and shows which commit each update is based upon. Added loads more checking.
This commit is contained in:
parent
53b3d09288
commit
743db9190e
@ -1,32 +0,0 @@
|
|||||||
#!/usr/bin/env bash
|
|
||||||
|
|
||||||
set -e
|
|
||||||
|
|
||||||
commit_msg="Rebased, XORed, auto-update JAR"
|
|
||||||
|
|
||||||
project=$( perl -n -e 'if (m/<artifactId>(\w+)<.artifactId>/) { print $1; exit }' pom.xml $)
|
|
||||||
|
|
||||||
echo 'Checking for previous JAR commit to remove'
|
|
||||||
top_commit=$(git log -n 1 --format=%s)
|
|
||||||
if [ "${top_commit}" = "${commit_msg}" ]; then
|
|
||||||
echo 'Removing previous JAR commit'
|
|
||||||
git reset --hard HEAD^
|
|
||||||
git push --force-with-lease
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo 'Rebasing using master branch'
|
|
||||||
git fetch -p origin
|
|
||||||
git rebase origin/master
|
|
||||||
|
|
||||||
echo 'Pushing rebased branch'
|
|
||||||
git push --force-with-lease
|
|
||||||
|
|
||||||
echo 'Building new XORed auto-update JAR'
|
|
||||||
mvn clean
|
|
||||||
mvn package
|
|
||||||
java -cp target/${project}*.jar org.qortal.XorUpdate target/${project}*.jar ${project}.update
|
|
||||||
|
|
||||||
echo 'Pushing new JAR commit'
|
|
||||||
git add ${project}.update
|
|
||||||
git commit -m "${commit_msg}"
|
|
||||||
git push
|
|
81
tools/build-auto-update.sh
Executable file
81
tools/build-auto-update.sh
Executable file
@ -0,0 +1,81 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
# Check we are within a git repo
|
||||||
|
git_dir=$( git rev-parse --show-toplevel )
|
||||||
|
if [ -z "${git_dir}" ]; then
|
||||||
|
echo "Cannot determine top-level directory for git repo"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Change to git top-level
|
||||||
|
cd ${git_dir}
|
||||||
|
|
||||||
|
# Check we are in 'master' branch
|
||||||
|
branch_name=$( git symbolic-ref -q HEAD )
|
||||||
|
branch_name=${branch_name##refs/heads/}
|
||||||
|
echo "Current git branch: ${branch_name}"
|
||||||
|
if [ "${branch_name}" != "master" ]; then
|
||||||
|
echo "Unexpected current branch '${branch_name}' - expecting 'master'"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Extract short-form commit hash
|
||||||
|
short_hash=$( git rev-parse --short HEAD )
|
||||||
|
if [ -z "${short_hash}" ]; then
|
||||||
|
echo "Unable to extract short-form current commit hash"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
echo "HEAD commit is: ${short_hash}"
|
||||||
|
|
||||||
|
# Check there are no uncommitted changes
|
||||||
|
uncommitted=$( git status --short --untracked-files=no )
|
||||||
|
if [ ! -z "${uncommitted}" ]; then
|
||||||
|
echo "Cannot continue due to uncommitted files:"
|
||||||
|
echo "${uncommitted}"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Determine project name
|
||||||
|
project=$( perl -n -e 'if (m/<artifactId>(\w+)<.artifactId>/) { print $1; exit }' pom.xml $)
|
||||||
|
if [ -z "${project}" ]; then
|
||||||
|
echo "Unable to determine project name from pom.xml?"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Actually rebuild JAR
|
||||||
|
echo "Building ${project} JAR..."
|
||||||
|
mvn clean package 1>/tmp/${project}-mvn-build.log 2>&1
|
||||||
|
if [ "$?" != "0" -o ! -r target/${project}*.jar ]; then
|
||||||
|
echo "Maven build failed. For details, see /tmp/${project}-mvn-build.log"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Convert packaged JAR to XORed update form
|
||||||
|
echo "Building ${project}.update..."
|
||||||
|
java -cp target/${project}*.jar org.qortal.XorUpdate target/${project}*.jar ${project}.update
|
||||||
|
if [ "$?" != "0" ]; then
|
||||||
|
echo "Failed to create XORed auto-update JAR"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Create auto-update branch from this commit
|
||||||
|
update_branch=auto-update-${short_hash}
|
||||||
|
|
||||||
|
if git show-ref --quiet --verify refs/heads/${update_branch}; then
|
||||||
|
echo "Existing auto-update branch based on this commit (${short_hash}) - deleting..."
|
||||||
|
git branch --delete --force ${update_branch}
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "Checking out new auto-update branch based on this commit (${short_hash})..."
|
||||||
|
git checkout --orphan ${update_branch}
|
||||||
|
git rm --cached -fr . 1>/dev/null
|
||||||
|
|
||||||
|
git add ${project}.update
|
||||||
|
|
||||||
|
git commit --message "XORed, auto-update JAR based on commit ${short_hash}"
|
||||||
|
git push --set-upstream origin --force-with-lease ${update_branch}
|
||||||
|
|
||||||
|
echo "Changing back to 'master' branch"
|
||||||
|
git checkout --force master
|
@ -1,5 +1,7 @@
|
|||||||
#!/usr/bin/env perl
|
#!/usr/bin/env perl
|
||||||
|
|
||||||
|
use strict;
|
||||||
|
use warnings;
|
||||||
use POSIX;
|
use POSIX;
|
||||||
use Getopt::Std;
|
use Getopt::Std;
|
||||||
|
|
||||||
@ -15,6 +17,12 @@ usage() unless @ARGV == 1;
|
|||||||
my $port = $opt{p} || 12391;
|
my $port = $opt{p} || 12391;
|
||||||
my $privkey = shift @ARGV;
|
my $privkey = shift @ARGV;
|
||||||
|
|
||||||
|
my $git_dir = `git rev-parse --show-toplevel`;
|
||||||
|
die("Cannot determine git top level dir\n") unless $git_dir;
|
||||||
|
|
||||||
|
chomp $git_dir;
|
||||||
|
chdir($git_dir) || die("Can't change directory to $git_dir: $!\n");
|
||||||
|
|
||||||
open(POM, '<', 'pom.xml') || die ("Can't open 'pom.xml': $!\n");
|
open(POM, '<', 'pom.xml') || die ("Can't open 'pom.xml': $!\n");
|
||||||
my $project;
|
my $project;
|
||||||
while (<POM>) {
|
while (<POM>) {
|
||||||
@ -25,82 +33,90 @@ while (<POM>) {
|
|||||||
}
|
}
|
||||||
close(POM);
|
close(POM);
|
||||||
|
|
||||||
open(PROPS, '-|', 'unzip -p target/${project}*.jar build.properties') || die("Can't extract 'build.properties' from JAR: $!\n");
|
# short-form commit hash on 'master' branch
|
||||||
while (<PROPS>) {
|
my $commit_hash = `git show --no-patch --format=%h`;
|
||||||
if (m/build.timestamp=(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2})Z/o) {
|
|
||||||
$timestamp = strftime('%s', $6, $5, $4, $3, $2 - 1, $1 - 1900, 0, 0, 0) * 1000;
|
|
||||||
last;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
close(PROPS);
|
|
||||||
|
|
||||||
die("Can't process build.timestamp\n") if ! defined $timestamp;
|
|
||||||
|
|
||||||
$commit_hash = `git show --no-patch --format=%H`;
|
|
||||||
|
|
||||||
die("Can't find commit hash\n") if ! defined $commit_hash;
|
die("Can't find commit hash\n") if ! defined $commit_hash;
|
||||||
chomp $commit_hash;
|
chomp $commit_hash;
|
||||||
|
printf "Commit hash on 'master' branch: %s\n", $commit_hash;
|
||||||
|
|
||||||
$sha256sum = `sha256sum ${project}.update 2>/dev/null || sha256 ${project}.update 2>/dev/null`;
|
# build timestamp / commit timestamp on 'master' branch
|
||||||
|
my $timestamp = `git show --no-patch --format=%ct`;
|
||||||
|
die("Can't determine commit timestamp\n") if ! defined $timestamp;
|
||||||
|
$timestamp *= 1000; # Convert to milliseconds
|
||||||
|
|
||||||
die("Can't calculate SHA256 of ${project}.update\n") unless $sha256sum =~ m/(\S{64})/;
|
# locate sha256 utility
|
||||||
|
my $SHA256 = `which sha256sum || which sha256`;
|
||||||
|
|
||||||
$sha256 = $1;
|
# SHA256 of actual update file
|
||||||
|
my $sha256 = `git show auto-update-${commit_hash}:${project}.update | ${SHA256}`;
|
||||||
|
die("Can't calculate SHA256 of ${project}.update\n") unless $sha256 =~ m/(\S{64})/;
|
||||||
|
chomp $sha256;
|
||||||
|
|
||||||
|
# long-form commit hash of HEAD on auto-update branch
|
||||||
|
my $update_hash = `git rev-parse refs/heads/auto-update-${commit_hash}`;
|
||||||
|
die("Can't find commit hash for HEAD on auto-update-${commit_hash} branch\n") if ! defined $update_hash;
|
||||||
|
chomp $update_hash;
|
||||||
|
|
||||||
printf "Build timestamp (ms): %d / 0x%016x\n", $timestamp, $timestamp;
|
printf "Build timestamp (ms): %d / 0x%016x\n", $timestamp, $timestamp;
|
||||||
printf "Commit hash: %s\n", $commit_hash;
|
printf "Auto-update commit hash: %s\n", $update_hash;
|
||||||
printf "SHA256 of ${project}.update: %s\n", $sha256;
|
printf "SHA256 of ${project}.update: %s\n", $sha256;
|
||||||
|
|
||||||
$tx_type = 10;
|
my $tx_type = 10;
|
||||||
$tx_timestamp = time() * 1000;
|
my $tx_timestamp = time() * 1000;
|
||||||
$tx_group_id = 1;
|
my $tx_group_id = 1;
|
||||||
$service = 1;
|
my $service = 1;
|
||||||
printf "\nARBITRARY(%d) transaction with timestamp %d, txGroupID %d and service %d\n", $tx_type, $tx_timestamp, $tx_group_id, $service;
|
printf "\nARBITRARY(%d) transaction with timestamp %d, txGroupID %d and service %d\n", $tx_type, $tx_timestamp, $tx_group_id, $service;
|
||||||
|
|
||||||
$data = sprintf "%016x%s%s", $timestamp, $commit_hash, $sha256;
|
my $data_hex = sprintf "%016x%s%s", $timestamp, $update_hash, $sha256;
|
||||||
printf "\nARBITRARY transaction data payload: %s\n", $data;
|
printf "\nARBITRARY transaction data payload: %s\n", $data_hex;
|
||||||
|
|
||||||
$n_payments = 0;
|
my $n_payments = 0;
|
||||||
$is_raw = 1; # RAW_DATA
|
my $is_raw = 1; # RAW_DATA
|
||||||
$data_length = length($data) / 2;
|
my $data_length = length($data_hex) / 2; # two hex chars per byte
|
||||||
$fee = 0.001 * 1e8;
|
my $fee = 0.001 * 1e8;
|
||||||
|
|
||||||
|
die("Something's wrong: data length is not 60 bytes!\n") if $data_length != 60;
|
||||||
|
|
||||||
my $pubkey = `curl --silent --url http://localhost:${port}/utils/publickey --data ${privkey}`;
|
my $pubkey = `curl --silent --url http://localhost:${port}/utils/publickey --data ${privkey}`;
|
||||||
die("Can't convert private key to public key!\n") unless $pubkey;
|
die("Can't convert private key to public key:\n$pubkey\n") unless $pubkey =~ m/^\w{44}$/;
|
||||||
printf "\nPublic key: %s\n", $pubkey;
|
printf "\nPublic key: %s\n", $pubkey;
|
||||||
|
|
||||||
my $pubkey_hex = `curl --silent --url http://localhost:${port}/utils/frombase58 --data ${pubkey}`;
|
my $pubkey_hex = `curl --silent --url http://localhost:${port}/utils/frombase58 --data ${pubkey}`;
|
||||||
|
die("Can't convert base58 public key to hex:\n$pubkey_hex\n") unless $pubkey_hex =~ m/^[A-Za-z0-9]{64}$/;
|
||||||
printf "Public key hex: %s\n", $pubkey_hex;
|
printf "Public key hex: %s\n", $pubkey_hex;
|
||||||
|
|
||||||
my $address = `curl --silent --url http://localhost:${port}/addresses/convert/${pubkey}`;
|
my $address = `curl --silent --url http://localhost:${port}/addresses/convert/${pubkey}`;
|
||||||
|
die("Can't convert base58 public key to address:\n$address\n") unless $address =~ m/^\w{34}$/;
|
||||||
printf "Address: %s\n", $address;
|
printf "Address: %s\n", $address;
|
||||||
|
|
||||||
my $reference = `curl --silent --url http://localhost:${port}/addresses/lastreference/${address}`;
|
my $reference = `curl --silent --url http://localhost:${port}/addresses/lastreference/${address}`;
|
||||||
|
die("Can't fetch last reference for $address:\n$reference\n") unless $reference =~ m/^\w{88}$/;
|
||||||
printf "Last reference: %s\n", $reference;
|
printf "Last reference: %s\n", $reference;
|
||||||
|
|
||||||
my $reference_hex = `curl --silent --url http://localhost:${port}/utils/frombase58 --data ${reference}`;
|
my $reference_hex = `curl --silent --url http://localhost:${port}/utils/frombase58 --data ${reference}`;
|
||||||
|
die("Can't convert base58 reference to hex:\n$reference_hex\n") unless $reference_hex =~ m/^[A-Za-z0-9]{128}$/;
|
||||||
printf "Last reference hex: %s\n", $reference_hex;
|
printf "Last reference hex: %s\n", $reference_hex;
|
||||||
|
|
||||||
my $raw_tx_hex = sprintf("%08x%016x%08x%s%s%08x%08x%02x%08x%s%016x", $tx_type, $tx_timestamp, $tx_group_id, $reference_hex, $pubkey_hex, $n_payments, $service, $is_raw, $data_length, $data, $fee);
|
my $raw_tx_hex = sprintf("%08x%016x%08x%s%s%08x%08x%02x%08x%s%016x", $tx_type, $tx_timestamp, $tx_group_id, $reference_hex, $pubkey_hex, $n_payments, $service, $is_raw, $data_length, $data_hex, $fee);
|
||||||
printf "\nRaw transaction hex:\n%s\n", $raw_tx_hex;
|
printf "\nRaw transaction hex:\n%s\n", $raw_tx_hex;
|
||||||
|
|
||||||
my $raw_tx = `curl --silent --url http://localhost:${port}/utils/tobase58/${raw_tx_hex}`;
|
my $raw_tx = `curl --silent --url http://localhost:${port}/utils/tobase58/${raw_tx_hex}`;
|
||||||
|
die("Can't convert raw transaction hex to base58:\n$raw_tx\n") unless $raw_tx =~ m/^\w{255,265}$/; # Roughly 255 to 265 base58 chars
|
||||||
printf "\nRaw transaction (base58):\n%s\n", $raw_tx;
|
printf "\nRaw transaction (base58):\n%s\n", $raw_tx;
|
||||||
|
|
||||||
my $sign_data = qq|' { "privateKey": "${privkey}", "transactionBytes": "${raw_tx}" } '|;
|
my $sign_data = qq|' { "privateKey": "${privkey}", "transactionBytes": "${raw_tx}" } '|;
|
||||||
my $signed_tx = `curl --silent -H "accept: text/plain" -H "Content-Type: application/json" --url http://localhost:${port}/transactions/sign --data ${sign_data}`;
|
my $signed_tx = `curl --silent -H "accept: text/plain" -H "Content-Type: application/json" --url http://localhost:${port}/transactions/sign --data ${sign_data}`;
|
||||||
|
die("Can't sign raw transaction:\n$signed_tx\n") unless $signed_tx =~ m/^\w{345,355}$/; # +90ish longer than $raw_tx
|
||||||
printf "\nSigned transaction:\n%s\n", $signed_tx;
|
printf "\nSigned transaction:\n%s\n", $signed_tx;
|
||||||
|
|
||||||
# Check we can actually fetch update
|
# Check we can actually fetch update
|
||||||
my $origin = `git remote get-url origin`;
|
my $origin = `git remote get-url origin`;
|
||||||
die("Unable to get github url for 'origin'?\n") unless $origin && $origin =~ m/:(.*)\.git$/;
|
die("Unable to get github url for 'origin'?\n") unless $origin && $origin =~ m/:(.*)\.git$/;
|
||||||
my $repo = $1;
|
my $repo = $1;
|
||||||
my $update_url = "https://github.com/${repo}/raw/${commit_hash}/${project}.update";
|
my $update_url = "https://github.com/${repo}/raw/${update_hash}/${project}.update";
|
||||||
|
|
||||||
my $fetch_result = `curl --silent -o /dev/null --location --range 0-1 --head --write-out '%{http_code}' --url ${update_url}`;
|
my $fetch_result = `curl --silent -o /dev/null --location --range 0-1 --head --write-out '%{http_code}' --url ${update_url}`;
|
||||||
if ($fetch_result ne '200') {
|
die("\nUnable to fetch update from ${update_url}\n") if $fetch_result ne '200';
|
||||||
die("\nUnable to fetch update from ${update_url}\n");
|
|
||||||
}
|
|
||||||
printf "\nUpdate fetchable from ${update_url}\n";
|
printf "\nUpdate fetchable from ${update_url}\n";
|
||||||
|
|
||||||
# Flush STDOUT after every output
|
# Flush STDOUT after every output
|
||||||
@ -113,4 +129,8 @@ for (my $delay = 5; $delay > 0; --$delay) {
|
|||||||
|
|
||||||
printf "\rSubmitting transaction NOW... \n";
|
printf "\rSubmitting transaction NOW... \n";
|
||||||
my $result = `curl --silent --url http://localhost:${port}/transactions/process --data ${signed_tx}`;
|
my $result = `curl --silent --url http://localhost:${port}/transactions/process --data ${signed_tx}`;
|
||||||
printf "\nTransaction accepted: %s\n", $result;
|
chomp $result;
|
||||||
|
die("Transaction wasn't accepted:\n$result\n") unless $result eq 'true';
|
||||||
|
|
||||||
|
my $decoded_tx = `curl --silent -H "Content-Type: application/json" --url http://localhost:${port}/transactions/decode --data ${signed_tx}`;
|
||||||
|
printf "\nTransaction accepted:\n$decoded_tx\n";
|
Loading…
Reference in New Issue
Block a user