diff --git a/.travis.yml b/.travis.yml
index b89e9bfed..20d9211aa 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -69,7 +69,7 @@ jobs:
directories:
- $BUILD_DIR
script:
- - ${ROOT_DIR}/pipeline/jobs/unittest_job.sh --testcategories Filter,Targeted,Purge,Serialization,WebApi,Utility,UriUtility,IO,ImportExport,Disruption,RestoreHandler
+ - ${ROOT_DIR}/pipeline/jobs/unittest_job.sh --testcategories Filter,Targeted,Purge,Serialization,WebApi,Utility,UriUtility,IO,ImportExport,Disruption,RestoreHandler,RepairHandler
- stage: tests
cache:
diff --git a/Duplicati/Library/AutoUpdater/UpdaterManager.cs b/Duplicati/Library/AutoUpdater/UpdaterManager.cs
index 9f7f16377..8d7b90955 100644
--- a/Duplicati/Library/AutoUpdater/UpdaterManager.cs
+++ b/Duplicati/Library/AutoUpdater/UpdaterManager.cs
@@ -850,7 +850,7 @@ namespace Duplicati.Library.AutoUpdater
{
string optstr = Environment.GetEnvironmentVariable(string.Format(UPDATE_STRATEGY_ENVNAME_TEMPLATE, APPNAME));
AutoUpdateStrategy strategy;
- if (string.IsNullOrWhiteSpace(optstr) || !Enum.TryParse(optstr, out strategy))
+ if (string.IsNullOrWhiteSpace(optstr) || !Enum.TryParse(optstr, true, out strategy))
strategy = defaultstrategy;
System.Threading.Thread backgroundChecker = null;
diff --git a/Duplicati/Library/Main/Operation/RepairHandler.cs b/Duplicati/Library/Main/Operation/RepairHandler.cs
index b189c79ea..eeb949ad7 100644
--- a/Duplicati/Library/Main/Operation/RepairHandler.cs
+++ b/Duplicati/Library/Main/Operation/RepairHandler.cs
@@ -309,138 +309,134 @@ namespace Duplicati.Library.Main.Operation
}
else if (n.Type == RemoteVolumeType.Index)
{
- using (IndexVolumeWriter w = new IndexVolumeWriter(m_options))
+ IndexVolumeWriter w = new IndexVolumeWriter(m_options);
+ newEntry = w;
+ w.SetRemoteFilename(n.Name);
+
+ var h = Library.Utility.HashAlgorithmHelper.Create(m_options.BlockHashAlgorithm);
+
+ foreach (var blockvolume in db.GetBlockVolumesFromIndexName(n.Name))
{
- newEntry = w;
- w.SetRemoteFilename(n.Name);
+ w.StartVolume(blockvolume.Name);
+ var volumeid = db.GetRemoteVolumeID(blockvolume.Name);
- var h = Library.Utility.HashAlgorithmHelper.Create(m_options.BlockHashAlgorithm);
+ foreach (var b in db.GetBlocks(volumeid))
+ w.AddBlock(b.Hash, b.Size);
- foreach (var blockvolume in db.GetBlockVolumesFromIndexName(n.Name))
- {
- w.StartVolume(blockvolume.Name);
- var volumeid = db.GetRemoteVolumeID(blockvolume.Name);
+ w.FinishVolume(blockvolume.Hash, blockvolume.Size);
- foreach (var b in db.GetBlocks(volumeid))
- w.AddBlock(b.Hash, b.Size);
+ if (m_options.IndexfilePolicy == Options.IndexFileStrategy.Full)
+ foreach (var b in db.GetBlocklists(volumeid, m_options.Blocksize, hashsize))
+ {
+ var bh = Convert.ToBase64String(h.ComputeHash(b.Item2, 0, b.Item3));
+ if (bh != b.Item1)
+ throw new Exception(string.Format("Internal consistency check failed, generated index block has wrong hash, {0} vs {1}", bh, b.Item1));
- w.FinishVolume(blockvolume.Hash, blockvolume.Size);
+ w.WriteBlocklist(b.Item1, b.Item2, 0, b.Item3);
+ }
+ }
- if (m_options.IndexfilePolicy == Options.IndexFileStrategy.Full)
- foreach (var b in db.GetBlocklists(volumeid, m_options.Blocksize, hashsize))
- {
- var bh = Convert.ToBase64String(h.ComputeHash(b.Item2, 0, b.Item3));
- if (bh != b.Item1)
- throw new Exception(string.Format("Internal consistency check failed, generated index block has wrong hash, {0} vs {1}", bh, b.Item1));
+ w.Close();
- w.WriteBlocklist(b.Item1, b.Item2, 0, b.Item3);
- }
- }
-
- w.Close();
-
- if (m_options.Dryrun)
- Logging.Log.WriteDryrunMessage(LOGTAG, "WouldReUploadIndexFile", "would re-upload index file {0}, with size {1}, previous size {2}", n.Name, Library.Utility.Utility.FormatSizeString(new System.IO.FileInfo(w.LocalFilename).Length), Library.Utility.Utility.FormatSizeString(n.Size));
- else
- {
- db.UpdateRemoteVolume(w.RemoteFilename, RemoteVolumeState.Uploading, -1, null, null);
- backend.Put(w);
- }
+ if (m_options.Dryrun)
+ Logging.Log.WriteDryrunMessage(LOGTAG, "WouldReUploadIndexFile", "would re-upload index file {0}, with size {1}, previous size {2}", n.Name, Library.Utility.Utility.FormatSizeString(new System.IO.FileInfo(w.LocalFilename).Length), Library.Utility.Utility.FormatSizeString(n.Size));
+ else
+ {
+ db.UpdateRemoteVolume(w.RemoteFilename, RemoteVolumeState.Uploading, -1, null, null);
+ backend.Put(w);
}
}
else if (n.Type == RemoteVolumeType.Blocks)
{
- using (BlockVolumeWriter w = new BlockVolumeWriter(m_options))
+ BlockVolumeWriter w = new BlockVolumeWriter(m_options);
+ newEntry = w;
+ w.SetRemoteFilename(n.Name);
+
+ using (var mbl = db.CreateBlockList(n.Name))
{
- newEntry = w;
- w.SetRemoteFilename(n.Name);
-
- using (var mbl = db.CreateBlockList(n.Name))
+ //First we grab all known blocks from local files
+ foreach (var block in mbl.GetSourceFilesWithBlocks(m_options.Blocksize))
{
- //First we grab all known blocks from local files
- foreach (var block in mbl.GetSourceFilesWithBlocks(m_options.Blocksize))
+ var hash = block.Hash;
+ var size = (int) block.Size;
+
+ foreach (var source in block.Sources)
{
- var hash = block.Hash;
- var size = (int) block.Size;
+ var file = source.File;
+ var offset = source.Offset;
- foreach (var source in block.Sources)
- {
- var file = source.File;
- var offset = source.Offset;
-
- try
- {
- if (System.IO.File.Exists(file))
- using (var f = System.IO.File.OpenRead(file))
- {
- f.Position = offset;
- if (size == Library.Utility.Utility.ForceStreamRead(f, buffer, size))
- {
- var newhash = Convert.ToBase64String(blockhasher.ComputeHash(buffer, 0, size));
- if (newhash == hash)
- {
- if (mbl.SetBlockRestored(hash, size))
- w.AddBlock(hash, buffer, 0, size, Duplicati.Library.Interface.CompressionHint.Default);
- break;
- }
- }
- }
- }
- catch (Exception ex)
- {
- Logging.Log.WriteErrorMessage(LOGTAG, "FileAccessError", ex, "Failed to access file: {0}", file);
- }
- }
- }
-
- //Then we grab all remote volumes that have the missing blocks
- foreach (var vol in new AsyncDownloader(mbl.GetMissingBlockSources().ToList(), backend))
- {
try
{
- using (var tmpfile = vol.TempFile)
- using (var f = new BlockVolumeReader(RestoreHandler.GetCompressionModule(vol.Name), tmpfile, m_options))
- foreach (var b in f.Blocks)
- if (mbl.SetBlockRestored(b.Key, b.Value))
- if (f.ReadBlock(b.Key, buffer) == b.Value)
- w.AddBlock(b.Key, buffer, 0, (int) b.Value, Duplicati.Library.Interface.CompressionHint.Default);
+ if (System.IO.File.Exists(file))
+ using (var f = System.IO.File.OpenRead(file))
+ {
+ f.Position = offset;
+ if (size == Library.Utility.Utility.ForceStreamRead(f, buffer, size))
+ {
+ var newhash = Convert.ToBase64String(blockhasher.ComputeHash(buffer, 0, size));
+ if (newhash == hash)
+ {
+ if (mbl.SetBlockRestored(hash, size))
+ w.AddBlock(hash, buffer, 0, size, Duplicati.Library.Interface.CompressionHint.Default);
+ break;
+ }
+ }
+ }
}
catch (Exception ex)
{
- Logging.Log.WriteErrorMessage(LOGTAG, "RemoteFileAccessError", ex, "Failed to access remote file: {0}", vol.Name);
+ Logging.Log.WriteErrorMessage(LOGTAG, "FileAccessError", ex, "Failed to access file: {0}", file);
}
}
+ }
- // If we managed to recover all blocks, NICE!
- var missingBlocks = mbl.GetMissingBlocks().Count();
- if (missingBlocks > 0)
+ //Then we grab all remote volumes that have the missing blocks
+ foreach (var vol in new AsyncDownloader(mbl.GetMissingBlockSources().ToList(), backend))
+ {
+ try
{
- Logging.Log.WriteInformationMessage(LOGTAG, "RepairMissingBlocks", "Repair cannot acquire {0} required blocks for volume {1}, which are required by the following filesets: ", missingBlocks, n.Name);
- foreach (var f in mbl.GetFilesetsUsingMissingBlocks())
- Logging.Log.WriteInformationMessage(LOGTAG, "AffectedFilesetName", f.Name);
+ using (var tmpfile = vol.TempFile)
+ using (var f = new BlockVolumeReader(RestoreHandler.GetCompressionModule(vol.Name), tmpfile, m_options))
+ foreach (var b in f.Blocks)
+ if (mbl.SetBlockRestored(b.Key, b.Value))
+ if (f.ReadBlock(b.Key, buffer) == b.Value)
+ w.AddBlock(b.Key, buffer, 0, (int) b.Value, Duplicati.Library.Interface.CompressionHint.Default);
+ }
+ catch (Exception ex)
+ {
+ Logging.Log.WriteErrorMessage(LOGTAG, "RemoteFileAccessError", ex, "Failed to access remote file: {0}", vol.Name);
+ }
+ }
- var recoverymsg = string.Format("If you want to continue working with the database, you can use the \"{0}\" and \"{1}\" commands to purge the missing data from the database and the remote storage.", "list-broken-files", "purge-broken-files");
+ // If we managed to recover all blocks, NICE!
+ var missingBlocks = mbl.GetMissingBlocks().Count();
+ if (missingBlocks > 0)
+ {
+ Logging.Log.WriteInformationMessage(LOGTAG, "RepairMissingBlocks", "Repair cannot acquire {0} required blocks for volume {1}, which are required by the following filesets: ", missingBlocks, n.Name);
+ foreach (var f in mbl.GetFilesetsUsingMissingBlocks())
+ Logging.Log.WriteInformationMessage(LOGTAG, "AffectedFilesetName", f.Name);
- if (!m_options.Dryrun)
- {
- Logging.Log.WriteInformationMessage(LOGTAG, "RecoverySuggestion", "This may be fixed by deleting the filesets and running repair again");
+ var recoverymsg = string.Format("If you want to continue working with the database, you can use the \"{0}\" and \"{1}\" commands to purge the missing data from the database and the remote storage.", "list-broken-files", "purge-broken-files");
- throw new UserInformationException(string.Format("Repair not possible, missing {0} blocks.\n" + recoverymsg, missingBlocks), "RepairIsNotPossible");
- }
- else
- {
- Logging.Log.WriteInformationMessage(LOGTAG, "RecoverySuggestion", recoverymsg);
- }
+ if (!m_options.Dryrun)
+ {
+ Logging.Log.WriteInformationMessage(LOGTAG, "RecoverySuggestion", "This may be fixed by deleting the filesets and running repair again");
+
+ throw new UserInformationException(string.Format("Repair not possible, missing {0} blocks.\n" + recoverymsg, missingBlocks), "RepairIsNotPossible");
}
else
{
- if (m_options.Dryrun)
- Logging.Log.WriteDryrunMessage(LOGTAG, "WouldReUploadBlockFile", "would re-upload block file {0}, with size {1}, previous size {2}", n.Name, Library.Utility.Utility.FormatSizeString(new System.IO.FileInfo(w.LocalFilename).Length), Library.Utility.Utility.FormatSizeString(n.Size));
- else
- {
- db.UpdateRemoteVolume(w.RemoteFilename, RemoteVolumeState.Uploading, -1, null, null);
- backend.Put(w);
- }
+ Logging.Log.WriteInformationMessage(LOGTAG, "RecoverySuggestion", recoverymsg);
+ }
+ }
+ else
+ {
+ if (m_options.Dryrun)
+ Logging.Log.WriteDryrunMessage(LOGTAG, "WouldReUploadBlockFile", "would re-upload block file {0}, with size {1}, previous size {2}", n.Name, Library.Utility.Utility.FormatSizeString(new System.IO.FileInfo(w.LocalFilename).Length), Library.Utility.Utility.FormatSizeString(n.Size));
+ else
+ {
+ db.UpdateRemoteVolume(w.RemoteFilename, RemoteVolumeState.Uploading, -1, null, null);
+ backend.Put(w);
}
}
}
diff --git a/Duplicati/Library/UsageReporter/Reporter.cs b/Duplicati/Library/UsageReporter/Reporter.cs
index d11036ac9..b4e568c02 100644
--- a/Duplicati/Library/UsageReporter/Reporter.cs
+++ b/Duplicati/Library/UsageReporter/Reporter.cs
@@ -173,7 +173,7 @@ namespace Duplicati.Library.UsageReporter
{
var str = Environment.GetEnvironmentVariable(string.Format(DISABLED_ENVNAME_TEMPLATE, AutoUpdater.AutoUpdateSettings.AppName));
ReportType tmp;
- if (string.IsNullOrWhiteSpace(str) || !Enum.TryParse(str, out tmp))
+ if (string.IsNullOrWhiteSpace(str) || !Enum.TryParse(str, true, out tmp))
Cached_MaxReportLevel = ReportType.Information;
else
Cached_MaxReportLevel = tmp;
diff --git a/Duplicati/UnitTest/Duplicati.UnitTest.csproj b/Duplicati/UnitTest/Duplicati.UnitTest.csproj
index 02ce5464f..6d7899dc7 100644
--- a/Duplicati/UnitTest/Duplicati.UnitTest.csproj
+++ b/Duplicati/UnitTest/Duplicati.UnitTest.csproj
@@ -204,4 +204,4 @@
-
\ No newline at end of file
+
diff --git a/Duplicati/UnitTest/RepairHandlerTests.cs b/Duplicati/UnitTest/RepairHandlerTests.cs
new file mode 100644
index 000000000..7c27bbee0
--- /dev/null
+++ b/Duplicati/UnitTest/RepairHandlerTests.cs
@@ -0,0 +1,48 @@
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using Duplicati.Library.Main;
+using NUnit.Framework;
+
+namespace Duplicati.UnitTest
+{
+ [TestFixture]
+ public class RepairHandlerTests : BasicSetupHelper
+ {
+ public override void SetUp()
+ {
+ base.SetUp();
+ File.WriteAllBytes(Path.Combine(this.DATAFOLDER, "file"), new byte[] {0});
+ }
+
+ [Test]
+ [Category("RepairHandler")]
+ [TestCase("true")]
+ [TestCase("false")]
+ public void RepairMissingIndexFiles(string noEncryption)
+ {
+ Dictionary options = new Dictionary(this.TestOptions) {["no-encryption"] = noEncryption};
+ using (Controller c = new Controller("file://" + this.TARGETFOLDER, options, null))
+ {
+ c.Backup(new[] {this.DATAFOLDER});
+ }
+
+ string[] dindexFiles = Directory.EnumerateFiles(this.TARGETFOLDER, "*dindex*").ToArray();
+ Assert.Greater(dindexFiles.Length, 0);
+ foreach (string f in dindexFiles)
+ {
+ File.Delete(f);
+ }
+
+ using (Controller c = new Controller("file://" + this.TARGETFOLDER, options, null))
+ {
+ c.Repair();
+ }
+
+ foreach (string file in dindexFiles)
+ {
+ Assert.IsTrue(File.Exists(Path.Combine(this.TARGETFOLDER, file)));
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/Installer/fedora/Dockerfile.build b/Installer/fedora/Dockerfile.build
index c14e576e7..556fb0d4e 100644
--- a/Installer/fedora/Dockerfile.build
+++ b/Installer/fedora/Dockerfile.build
@@ -9,6 +9,12 @@ RUN dnf -y install deltarpm
RUN dnf -y upgrade
RUN dnf -y --allowerasing install @"Minimal Install" @buildsys-build yum-utils rpm-sign gnupg rpmdevtools
+# Install real mono for building
+# Instructions from here: https://www.mono-project.com/download/stable/#download-lin-fedora
+RUN rpm --import "https://keyserver.ubuntu.com/pks/lookup?op=get&search=0x3FA7E0328081BFF6A14DA29AA6A19B38D3D831EF"
+RUN curl https://download.mono-project.com/repo/centos8-stable.repo | tee /etc/yum.repos.d/mono-centos8-stable.repo
+RUN dnf -y update
+
# Install mono things
RUN dnf -y install mono-devel gnome-sharp-devel dos2unix git nuget
diff --git a/build-installers.sh b/build-installers.sh
index 508c404c0..6d3459e3b 100755
--- a/build-installers.sh
+++ b/build-installers.sh
@@ -26,6 +26,9 @@ MONO=/Library/Frameworks/Mono.framework/Commands/mono
GPG=/usr/local/bin/gpg2
+# Newer GPG needs this to allow input from a non-terminal
+export GPG_TTY=$(tty)
+
ZIPFILE=$(basename "$1")
VERSION=$(echo "${ZIPFILE}" | cut -d "-" -f 2 | cut -d "_" -f 1)
BUILDTYPE=$(echo "${ZIPFILE}" | cut -d "-" -f 2 | cut -d "_" -f 2)
@@ -52,9 +55,18 @@ echo "DEBName: ${DEBNAME}"
echo "SPKName: ${SPKNAME}"
build_file_signatures() {
- if [ "z${GPGID}" != "z" ]; then
- echo "$GPGKEY" | "${GPG}" "--passphrase-fd" "0" "--batch" "--yes" "--default-key=${GPGID}" "--output" "$2.sig" "--detach-sig" "$1"
- echo "$GPGKEY" | "${GPG}" "--passphrase-fd" "0" "--batch" "--yes" "--default-key=${GPGID}" "--armor" "--output" "$2.sig.asc" "--detach-sig" "$1"
+ if [ -f "${GPG_KEYFILE}" ]; then
+ "${MONO}" "BuildTools/GnupgSigningTool/bin/Debug/GnupgSigningTool.exe" \
+ --inputfile=\"$1\" \
+ --signaturefile=\"$2.sig\" \
+ --armor=false --gpgkeyfile="${GPG_KEYFILE}" --gpgpath="${GPG}" \
+ --keyfile-password="${KEYFILE_PASSWORD}"
+
+ "${MONO}" "BuildTools/GnupgSigningTool/bin/Debug/GnupgSigningTool.exe" \
+ --inputfile=\"$1\" \
+ --signaturefile=\"$2.sig.asc\" \
+ --armor=true --gpgkeyfile="${GPG_KEYFILE}" --gpgpath="${GPG}" \
+ --keyfile-password="${KEYFILE_PASSWORD}"
fi
md5 "$1" | awk -F ' ' '{print $NF}' > "$2.md5"
diff --git a/build-release.sh b/build-release.sh
index 75d164947..a747b8c51 100644
--- a/build-release.sh
+++ b/build-release.sh
@@ -33,6 +33,8 @@ XBUILD=/Library/Frameworks/Mono.framework/Commands/msbuild
NUGET=/Library/Frameworks/Mono.framework/Commands/nuget
MONO=/Library/Frameworks/Mono.framework/Commands/mono
GPG=/usr/local/bin/gpg2
+AWS=/usr/local/bin/aws
+GITHUB_RELEASE=/usr/local/bin/github-release
# Newer GPG needs this to allow input from a non-terminal
export GPG_TTY=$(tty)
@@ -57,6 +59,18 @@ if [ ! -f "$NUGET" ]; then
exit 1
fi
+if [ ! -f "$AWS" ]; then
+ echo "aws-cli not found: $AWS"
+ exit 1
+fi
+
+if [ ! -f "$GITHUB_RELEASE" ]; then
+ echo "github-release executable not found: $GITHUB_RELEASE"
+ echo "Grab it from: https://github.com/aktau/github-release"
+ exit 1
+fi
+
+
# The "OTHER_UPLOADS" setting is no longer used
if [ "${RELEASE_TYPE}" == "nightly" ]; then
OTHER_UPLOADS=""
@@ -281,12 +295,12 @@ cp "${UPDATE_TARGET}/latest.zip.sig.asc" "${UPDATE_TARGET}/${RELEASE_FILE_NAME}.
"${MONO}" "BuildTools/UpdateVersionStamp/bin/Debug/UpdateVersionStamp.exe" --version="2.0.0.7"
echo "Uploading binaries"
-aws --profile=duplicati-upload s3 cp "${UPDATE_TARGET}/${RELEASE_FILE_NAME}.zip" "s3://updates.duplicati.com/${RELEASE_TYPE}/${RELEASE_FILE_NAME}.zip"
-aws --profile=duplicati-upload s3 cp "${UPDATE_TARGET}/${RELEASE_FILE_NAME}.zip.sig" "s3://updates.duplicati.com/${RELEASE_TYPE}/${RELEASE_FILE_NAME}.zip.sig"
-aws --profile=duplicati-upload s3 cp "${UPDATE_TARGET}/${RELEASE_FILE_NAME}.zip.sig.asc" "s3://updates.duplicati.com/${RELEASE_TYPE}/${RELEASE_FILE_NAME}.zip.sig.asc"
-aws --profile=duplicati-upload s3 cp "${UPDATE_TARGET}/${RELEASE_FILE_NAME}.manifest" "s3://updates.duplicati.com/${RELEASE_TYPE}/${RELEASE_FILE_NAME}.manifest"
+"${AWS}" --profile=duplicati-upload s3 cp "${UPDATE_TARGET}/${RELEASE_FILE_NAME}.zip" "s3://updates.duplicati.com/${RELEASE_TYPE}/${RELEASE_FILE_NAME}.zip"
+"${AWS}" --profile=duplicati-upload s3 cp "${UPDATE_TARGET}/${RELEASE_FILE_NAME}.zip.sig" "s3://updates.duplicati.com/${RELEASE_TYPE}/${RELEASE_FILE_NAME}.zip.sig"
+"${AWS}" --profile=duplicati-upload s3 cp "${UPDATE_TARGET}/${RELEASE_FILE_NAME}.zip.sig.asc" "s3://updates.duplicati.com/${RELEASE_TYPE}/${RELEASE_FILE_NAME}.zip.sig.asc"
+"${AWS}" --profile=duplicati-upload s3 cp "${UPDATE_TARGET}/${RELEASE_FILE_NAME}.manifest" "s3://updates.duplicati.com/${RELEASE_TYPE}/${RELEASE_FILE_NAME}.manifest"
-aws --profile=duplicati-upload s3 cp "s3://updates.duplicati.com/${RELEASE_TYPE}/${RELEASE_FILE_NAME}.manifest" "s3://updates.duplicati.com/${RELEASE_TYPE}/latest.manifest"
+"${AWS}" --profile=duplicati-upload s3 cp "s3://updates.duplicati.com/${RELEASE_TYPE}/${RELEASE_FILE_NAME}.manifest" "s3://updates.duplicati.com/${RELEASE_TYPE}/latest.manifest"
ZIP_MD5=$(md5 ${UPDATE_TARGET}/${RELEASE_FILE_NAME}.zip | awk -F ' ' '{print $NF}')
ZIP_SHA1=$(shasum -a 1 ${UPDATE_TARGET}/${RELEASE_FILE_NAME}.zip | awk -F ' ' '{print $1}')
@@ -311,8 +325,8 @@ echo "duplicati_version_info =" > "latest.js"
cat "latest.json" >> "latest.js"
echo ";" >> "latest.js"
-aws --profile=duplicati-upload s3 cp "latest.json" "s3://updates.duplicati.com/${RELEASE_TYPE}/latest.json"
-aws --profile=duplicati-upload s3 cp "latest.js" "s3://updates.duplicati.com/${RELEASE_TYPE}/latest.js"
+"${AWS}" --profile=duplicati-upload s3 cp "latest.json" "s3://updates.duplicati.com/${RELEASE_TYPE}/latest.json"
+"${AWS}" --profile=duplicati-upload s3 cp "latest.js" "s3://updates.duplicati.com/${RELEASE_TYPE}/latest.js"
# echo "Propagating to other build types"
# for OTHER in ${OTHER_UPLOADS}; do
@@ -338,14 +352,12 @@ fi
RELEASE_MESSAGE=$(printf "Changes in this version:\n${RELEASE_CHANGEINFO_NEWS}")
-# Using the tool from https://github.com/aktau/github-release
-
GITHUB_TOKEN=$(cat "${GITHUB_TOKEN_FILE}")
if [ "x${GITHUB_TOKEN}" == "x" ]; then
echo "No GITHUB_TOKEN found in environment, you can manually upload the binaries"
else
- github-release release ${PRE_RELEASE_LABEL} \
+ "${GITHUB_RELEASE}" release ${PRE_RELEASE_LABEL} \
--tag "v${RELEASE_VERSION}-${RELEASE_NAME}" \
--name "v${RELEASE_VERSION}-${RELEASE_NAME}" \
--repo "duplicati" \
@@ -353,7 +365,7 @@ else
--security-token "${GITHUB_TOKEN}" \
--description "${RELEASE_MESSAGE}" \
- github-release upload \
+ "${GITHUB_RELEASE}" upload \
--tag "v${RELEASE_VERSION}-${RELEASE_NAME}" \
--name "${RELEASE_FILE_NAME}.zip" \
--repo "duplicati" \
diff --git a/pipeline/start.sh b/pipeline/start.sh
index 801148791..d052abd94 100755
--- a/pipeline/start.sh
+++ b/pipeline/start.sh
@@ -8,5 +8,5 @@ ${ROOT_DIR}/pipeline/jobs/unittest_job.sh --testcategories BulkNormal
${ROOT_DIR}/pipeline/jobs/unittest_job.sh --testcategories BulkNoSize
${ROOT_DIR}/pipeline/jobs/unittest_job.sh --testcategories SVNDataLong,SVNData,RecoveryTool
${ROOT_DIR}/pipeline/jobs/unittest_job.sh --testcategories Border
-${ROOT_DIR}/pipeline/jobs/unittest_job.sh --testcategories Filter,Targeted,Purge,Serialization,WebApi,Utility,UriUtility,IO,ImportExport,Disruption,RestoreHandler
+${ROOT_DIR}/pipeline/jobs/unittest_job.sh --testcategories Filter,Targeted,Purge,Serialization,WebApi,Utility,UriUtility,IO,ImportExport,Disruption,RestoreHandler,RepairHandler