Removed unused files.

Moved installer files into the ReleaseBuilder
This commit is contained in:
Kenneth Skovhede
2024-04-23 14:24:38 +02:00
parent 0b566ecf1f
commit b73e94de7e
64 changed files with 43 additions and 1793 deletions
-105
View File
@@ -1,105 +0,0 @@
name: Artifacts
on:
push:
branches: "**net5**"
pull_request:
branches: "**net5**"
jobs:
zip:
runs-on: ${{ matrix.cfg.os }}
strategy:
fail-fast: false
matrix:
cfg:
- { os: ubuntu-latest, runtime: linux-x64 }
- { os: windows-latest, runtime: win-x64 }
- { os: macos-latest, runtime: osx-x64 }
steps:
- uses: actions/checkout@v2
- name: Setup .NET
uses: actions/setup-dotnet@v1
with:
dotnet-version: 6.0.x
- name: Restore dependencies
run: dotnet restore --runtime=${{ matrix.cfg.runtime }} Duplicati.sln
- name: Package
#TODO: investigate #if __WindowsGTK__ || ENABLE_GTK via -p:DefineConstants=ENABLE_GTK Maybe needed for GUI?
run: dotnet publish -c Release --runtime=${{ matrix.cfg.runtime }} -o publish Duplicati.sln
- name: Save Artifacts
uses: actions/upload-artifact@v2
with:
name: duplicati-${{ matrix.cfg.runtime }}
path: publish
deb:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Package
run: Installer/debian/build.sh
- name: Save Artifacts
uses: actions/upload-artifact@v2
with:
name: deb package
path: duplicati*.deb
rpm:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Package
run: Installer/fedora/build.sh
- name: Save Artifacts
uses: actions/upload-artifact@v2
with:
name: rpm package
path: duplicati*.rpm
msi:
runs-on: windows-latest
needs: zip
steps:
- name: Checkout
uses: actions/checkout@v2
- name: Download zip
uses: actions/download-artifact@v2
with:
name: duplicati-win-x64
path: bin
- name: Install go-msi
run: choco install -y "go-msi"
- name: Prepare PATH
shell: bash
run: |
echo "$WIX\\bin" >> $GITHUB_PATH
echo "C:\\Program Files\\go-msi" >> $GITHUB_PATH
- name: Build MSI
id: buildmsi
shell: bash
run: |
Installer/Windows/MSI/build.sh
- name: Save Artifacts
uses: actions/upload-artifact@v2
with:
name: duplicati-win-x64-msi
path: duplicati-win-x64.msi
dmg:
runs-on: macos-latest
needs: zip
steps:
- name: Checkout
uses: actions/checkout@v2
- name: Download zip
uses: actions/download-artifact@v2
with:
name: duplicati-osx-x64
path: bin
- name: Build DMG
shell: bash
run: |
Installer/OSX/dmg/build.sh
- name: Save Artifacts
uses: actions/upload-artifact@v2
with:
name: Duplicati.dmg
path: Duplicati.dmg
-105
View File
@@ -1,105 +0,0 @@
name: Build release installers
on:
workflow_dispatch
env:
build_directory: "Duplicati/GUI/Duplicati.GUI.TrayIcon/bin/Release"
jobs:
macbuild:
name: mac build and installers
runs-on: macos-latest
strategy:
fail-fast: false
steps:
- name: Install NuGet
uses: nuget/setup-nuget@v1.1.1
- name: Checkout Source
uses: actions/checkout@v3
- name: Restore NuGet Packages
run: |
nuget restore Duplicati.sln
nuget restore "BuildTools/UpdateVersionStamp/UpdateVersionStamp.sln"
- name: Build Duplicati (macOS)
run: |
msbuild /property:Configuration=Release "BuildTools/UpdateVersionStamp/UpdateVersionStamp.sln"
RELEASE_TIMESTAMP=$(date +%Y-%m-%d)
RELEASE_TYPE="canary"
RELEASE_INC_VERSION=$(cat Updates/build_version.txt)
RELEASE_INC_VERSION=$((RELEASE_INC_VERSION+1))
RELEASE_VERSION="2.0.7.${RELEASE_INC_VERSION}"
RELEASE_NAME="${RELEASE_VERSION}_${RELEASE_TYPE}_${RELEASE_TIMESTAMP}"
echo "${RELEASE_NAME}" > "Duplicati/License/VersionTag.txt"
echo "${RELEASE_TYPE}" > "Duplicati/Library/AutoUpdater/AutoUpdateBuildChannel.txt"
mono "BuildTools/UpdateVersionStamp/bin/Release/UpdateVersionStamp.exe" --version="${RELEASE_VERSION}"
msbuild -p:DefineConstants=\"ENABLE_GTK\;XAMARIN_MAC\" -p:Configuration=Release Duplicati.sln
- name: Build installers (OSX)
run: |
Installer/OSX/artifact_mac.sh
- name: Upload build results
uses: actions/upload-artifact@v3
with:
retention-days: 5
name: build-results-mac
path: ~/artifacts/**/*
windowsbuild:
name: windows installer
runs-on: windows-latest
needs: macbuild
steps:
- name: Add msbuild to PATH
uses: microsoft/setup-msbuild@v1.3
- name: Install NuGet
uses: nuget/setup-nuget@v1.1.1
- uses: actions/checkout@v3
- name: Retrieve mac build
uses: actions/download-artifact@v3
with:
name: build-results-mac
path: ~/macartifacts
- name: set env
run: echo "ZIPBUILDFILE=$(resolve-path ~ | select-object -expandproperty path)\macartifacts\$(get-childitem ~\macartifacts\*.zip | select-object -first 1 -expandproperty name )" >> $env:GITHUB_ENV
- name: Build installers (Windows)
run: |
echo ${{ env.ZIPBUILDFILE }}
.\\Installer\\Windows\\artifact_win.bat ${{ env.ZIPBUILDFILE }}
- name: Upload build results
uses: actions/upload-artifact@v3
with:
retention-days: 5
name: build-results-windows
path: ~/artifacts/**/*
debianbuild:
name: debian like installer
runs-on: ubuntu-latest
needs: macbuild
steps:
- uses: actions/checkout@v3
- name: Retrieve mac build
uses: actions/download-artifact@v3
with:
name: build-results-mac
path: ~/macartifacts
- name: set env
run: echo "ZIPBUILDFILE=$(ls ~/macartifacts/*.zip | tail -1)" >> $GITHUB_ENV
- name: Build installers (Deb)
run: |
echo ${{ env.ZIPBUILDFILE }}
sudo apt install debhelper
Installer/debian/artifact_deb.sh ${{ env.ZIPBUILDFILE }}
- name: Upload build results
uses: actions/upload-artifact@v3
with:
retention-days: 5
name: build-results-linux
path: ~/artifacts/**/*
-108
View File
@@ -1,108 +0,0 @@
name: Build release installers from PR
on:
pull_request:
types: [ labeled ]
env:
build_directory: "Duplicati/GUI/Duplicati.GUI.TrayIcon/bin/Release"
jobs:
macbuild:
if: ${{ github.event.label.name == 'testbuild' }}
name: mac build and installers
runs-on: macos-latest
strategy:
fail-fast: false
steps:
- name: Install NuGet
uses: nuget/setup-nuget@v1.1.1
- name: Checkout Source
uses: actions/checkout@v3
- name: Restore NuGet Packages
run: |
nuget restore Duplicati.sln
nuget restore "BuildTools/UpdateVersionStamp/UpdateVersionStamp.sln"
- name: Build Duplicati (macOS)
run: |
msbuild /property:Configuration=Release "BuildTools/UpdateVersionStamp/UpdateVersionStamp.sln"
RELEASE_TIMESTAMP=$(date +%Y-%m-%d)
RELEASE_TYPE="canary"
RELEASE_INC_VERSION=$(cat Updates/build_version.txt)
RELEASE_INC_VERSION=$((RELEASE_INC_VERSION+1))
RELEASE_VERSION="2.0.7.${RELEASE_INC_VERSION}"
RELEASE_NAME="${RELEASE_VERSION}_${RELEASE_TYPE}_${RELEASE_TIMESTAMP}"
echo "${RELEASE_NAME}" > "Duplicati/License/VersionTag.txt"
echo "${RELEASE_TYPE}" > "Duplicati/Library/AutoUpdater/AutoUpdateBuildChannel.txt"
mono "BuildTools/UpdateVersionStamp/bin/Release/UpdateVersionStamp.exe" --version="${RELEASE_VERSION}"
msbuild -p:DefineConstants=\"ENABLE_GTK\;XAMARIN_MAC\" -p:Configuration=Release Duplicati.sln
- name: Build installers (OSX)
run: |
Installer/OSX/artifact_mac.sh
- name: Upload build results
uses: actions/upload-artifact@v3
with:
retention-days: 5
name: build-results-mac
path: ~/artifacts/**/*
windowsbuild:
name: windows installer
runs-on: windows-latest
needs: macbuild
steps:
- name: Add msbuild to PATH
uses: microsoft/setup-msbuild@v1.3
- name: Install NuGet
uses: nuget/setup-nuget@v1.1.1
- uses: actions/checkout@v3
- name: Retrieve mac build
uses: actions/download-artifact@v3
with:
name: build-results-mac
path: ~/macartifacts
- name: set env
run: echo "ZIPBUILDFILE=$(resolve-path ~ | select-object -expandproperty path)\macartifacts\$(get-childitem ~\macartifacts\*.zip | select-object -first 1 -expandproperty name )" >> $env:GITHUB_ENV
- name: Build installers (Windows)
run: |
echo ${{ env.ZIPBUILDFILE }}
.\\Installer\\Windows\\artifact_win.bat ${{ env.ZIPBUILDFILE }}
- name: Upload build results
uses: actions/upload-artifact@v3
with:
retention-days: 5
name: build-results-windows
path: ~/artifacts/**/*
debianbuild:
name: debian like installer
runs-on: ubuntu-latest
needs: macbuild
steps:
- uses: actions/checkout@v3
- name: Retrieve mac build
uses: actions/download-artifact@v3
with:
name: build-results-mac
path: ~/macartifacts
- name: set env
run: echo "ZIPBUILDFILE=$(ls ~/macartifacts/*.zip | tail -1)" >> $GITHUB_ENV
- name: Build installers (Deb)
run: |
echo ${{ env.ZIPBUILDFILE }}
sudo apt install debhelper
Installer/debian/artifact_deb.sh ${{ env.ZIPBUILDFILE }}
- name: Upload build results
uses: actions/upload-artifact@v3
with:
retention-days: 5
name: build-results-linux
path: ~/artifacts/**/*
+2 -14
View File
@@ -4,29 +4,17 @@ obj/
*.userprefs
*.user
*.suo
Installer/Paraffin.exe
Installer/account_info
Duplicati/Localization/compiled
Duplicati/Localization/*/
Duplicati/Localization/*.diff.csv
Duplicati/Localization/*.new.csv
Duplicati/Localization/*.updated.csv
Duplicati/Localization/report.*.xml
Installer/incLocFiles.*.wxs
Duplicati/Server/webroot/extjs-*
Installer/binfiles.wxs
Installer/generated-keys.xml
Installer/oem
Updates/build
packages
changelog-news.txt
binfiles.wxs
.idea/
.vs/
/publish/
Installer/debian/*.buildinfo
/*.deb
/*.rpm
ReleaseBuilder/build-temp/
ReleaseBuilder/build-temp/
ReleaseBuilder/Resources/Windows/binfiles.wxs
@@ -1,19 +0,0 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<OutputType>Exe</OutputType>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Mono.Cecil" Version="0.11.5" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.DotNet.Analyzers.Compatibility" Version="0.2.12-alpha">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
</ItemGroup>
</Project>
@@ -1,17 +0,0 @@
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 2012
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DependencyFinder", "DependencyFinder.csproj", "{3E891818-579A-4C06-8066-4C702BFA5921}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|x86 = Debug|x86
Release|x86 = Release|x86
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{3E891818-579A-4C06-8066-4C702BFA5921}.Debug|x86.ActiveCfg = Debug|x86
{3E891818-579A-4C06-8066-4C702BFA5921}.Debug|x86.Build.0 = Debug|x86
{3E891818-579A-4C06-8066-4C702BFA5921}.Release|x86.ActiveCfg = Release|x86
{3E891818-579A-4C06-8066-4C702BFA5921}.Release|x86.Build.0 = Release|x86
EndGlobalSection
EndGlobal
-85
View File
@@ -1,85 +0,0 @@
// Copyright (C) 2024, The Duplicati Team
// https://duplicati.com, hello@duplicati.com
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
using System;
using System.Collections.Generic;
using Mono.Cecil;
using System.IO;
using System.Linq;
namespace DependencyFinder
{
class MainClass
{
public static void Main(string[] args)
{
var lst =
Directory.EnumerateFiles(args[0], "*.exe", SearchOption.AllDirectories).Union(
Directory.EnumerateFiles(args[0], "*.dll", SearchOption.AllDirectories))
.Select(x => {
try { return AssemblyDefinition.ReadAssembly(x); }
catch { return null; }
}).Where(x => x != null)
.Distinct();
PoC(lst, Console.Out, new [] { args[0] });
}
//Adapted from: https://stackoverflow.com/questions/9262464/tool-to-show-assembly-dependencies
public static void PoC(IEnumerable<AssemblyDefinition> assemblies, TextWriter writer, IEnumerable<string> searchfolders)
{
var resolver = new DefaultAssemblyResolver();
searchfolders.ToList().ForEach(x => resolver.AddSearchDirectory(x));
//writer.WriteLine("digraph Dependencies {");
var loaded = assemblies
.SelectMany(a => a.Modules.Cast<ModuleDefinition>())
.SelectMany(m => m.AssemblyReferences.Cast<AssemblyNameReference>())
.Distinct()
.Select(asm => {
var dllname = asm.Name + ".dll";
//Console.WriteLine("Probing for {0}", dllname);
try { return AssemblyDefinition.ReadAssembly(dllname); }
catch { }
try { return resolver.Resolve(asm); }
catch { }
return null;
})
.Where(assembly => assembly != null)
.ToList();
//loaded.ForEach(a => a.MainModule.ReadSymbols());
loaded.Select(x => x.FullName).Distinct().OrderBy(x => x).ToList().ForEach(x => writer.WriteLine("{0}", x));
/*loaded.ForEach(a =>
{
foreach (var r in a.MainModule.AssemblyReferences.Cast<AssemblyNameReference>())
writer.WriteLine(@"""{0}"" -> ""{1}"";", r.Name, a.Name.Name);
} );*/
//writer.WriteLine("}");
}
}
}
@@ -1,21 +0,0 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<OutputType>Exe</OutputType>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\..\Duplicati\Library\Interface\Duplicati.Library.Interface.csproj" />
<ProjectReference Include="..\..\Duplicati\Library\Encryption\Duplicati.Library.Encryption.csproj" />
<ProjectReference Include="..\..\Duplicati\Library\Utility\Duplicati.Library.Utility.csproj" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.DotNet.Analyzers.Compatibility" Version="0.2.12-alpha">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
</ItemGroup>
</Project>
@@ -1,42 +0,0 @@
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 16
VisualStudioVersion = 16.0.29123.88
MinimumVisualStudioVersion = 10.0.40219.1
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "GnupgSigningTool", "GnupgSigningTool.csproj", "{72B910F2-8E80-4955-A0D6-ED4C35CEE665}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Duplicati.Library.Utility", "..\..\Duplicati\Library\Utility\Duplicati.Library.Utility.csproj", "{DE3E5D4C-51AB-4E5E-BEE8-E636CEBFBA65}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Duplicati.Library.Encryption", "..\..\Duplicati\Library\Encryption\Duplicati.Library.Encryption.csproj", "{2CF2D90E-C25B-47AD-91E0-98451BAB8058}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Duplicati.Library.Interface", "..\..\Duplicati\Library\Interface\Duplicati.Library.Interface.csproj", "{C5899F45-B0FF-483C-9D38-24A9FCAAB237}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|x86 = Debug|x86
Release|x86 = Release|x86
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{72B910F2-8E80-4955-A0D6-ED4C35CEE665}.Debug|x86.ActiveCfg = Debug|x86
{72B910F2-8E80-4955-A0D6-ED4C35CEE665}.Debug|x86.Build.0 = Debug|x86
{72B910F2-8E80-4955-A0D6-ED4C35CEE665}.Release|x86.ActiveCfg = Release|x86
{72B910F2-8E80-4955-A0D6-ED4C35CEE665}.Release|x86.Build.0 = Release|x86
{DE3E5D4C-51AB-4E5E-BEE8-E636CEBFBA65}.Debug|x86.ActiveCfg = Debug|Any CPU
{DE3E5D4C-51AB-4E5E-BEE8-E636CEBFBA65}.Debug|x86.Build.0 = Debug|Any CPU
{DE3E5D4C-51AB-4E5E-BEE8-E636CEBFBA65}.Release|x86.ActiveCfg = Release|Any CPU
{DE3E5D4C-51AB-4E5E-BEE8-E636CEBFBA65}.Release|x86.Build.0 = Release|Any CPU
{2CF2D90E-C25B-47AD-91E0-98451BAB8058}.Debug|x86.ActiveCfg = Debug|Any CPU
{2CF2D90E-C25B-47AD-91E0-98451BAB8058}.Debug|x86.Build.0 = Debug|Any CPU
{2CF2D90E-C25B-47AD-91E0-98451BAB8058}.Release|x86.ActiveCfg = Release|Any CPU
{2CF2D90E-C25B-47AD-91E0-98451BAB8058}.Release|x86.Build.0 = Release|Any CPU
{C5899F45-B0FF-483C-9D38-24A9FCAAB237}.Debug|x86.ActiveCfg = Debug|Any CPU
{C5899F45-B0FF-483C-9D38-24A9FCAAB237}.Debug|x86.Build.0 = Debug|Any CPU
{C5899F45-B0FF-483C-9D38-24A9FCAAB237}.Release|x86.ActiveCfg = Release|Any CPU
{C5899F45-B0FF-483C-9D38-24A9FCAAB237}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {71CC6B1F-7F52-4059-8761-30B3D0501ECC}
EndGlobalSection
EndGlobal
-128
View File
@@ -1,128 +0,0 @@
// Copyright (C) 2024, The Duplicati Team
// https://duplicati.com, hello@duplicati.com
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
using System;
using System.Collections.Generic;
namespace GnupgSigningTool
{
public static class Program
{
private static string keyfilepassword;
private static string gpgkeypassphrase;
private static string gpgkeyfile;
private static string gpgpath;
private static string gpgkeyid;
private static bool useArmor;
private static string inputFile;
private static string signatureFile;
private static void SpawnGPG()
{
var armorOption = useArmor ? "--armor" : "";
var gpgArgument = string.Format("--pinentry-mode loopback --passphrase-fd 0 --batch --yes {0} -u \"{1}\" --output \"{2}\" --detach-sig \"{3}\"",
armorOption,
gpgkeyid,
signatureFile,
inputFile);
var proc = System.Diagnostics.Process.Start(new System.Diagnostics.ProcessStartInfo
{
FileName = gpgpath,
Arguments = gpgArgument,
RedirectStandardInput = true,
UseShellExecute = false
});
proc.StandardInput.WriteLine(gpgkeypassphrase);
proc.WaitForExit();
}
private static void LoadGPGKeyIdAndPassphrase()
{
using (var enc = new Duplicati.Library.Encryption.AESEncryption(keyfilepassword, new Dictionary<string, string>()))
using (var ms = new System.IO.MemoryStream())
using (var fs = System.IO.File.OpenRead(gpgkeyfile))
{
try
{
enc.Decrypt(fs, ms);
}
catch (System.Security.Cryptography.CryptographicException e)
{
throw new ArgumentException("Failed to decrypt gpg secret credentials file: {0}\n", e.Message);
}
ms.Position = 0;
using (var sr = new System.IO.StreamReader(ms))
{
var lines = sr.ReadToEnd().Split(new[] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries);
gpgkeyid = lines[0];
gpgkeypassphrase = lines[1];
}
}
}
public static void Main(string[] _args)
{
var args = new List<string>(_args);
var opts = Duplicati.Library.Utility.CommandLineParser.ExtractOptions(args);
opts.TryGetValue("inputfile", out inputFile);
opts.TryGetValue("signaturefile", out signatureFile);
opts.TryGetValue("keyfile-password", out keyfilepassword);
opts.TryGetValue("gpgkeyfile", out gpgkeyfile);
opts.TryGetValue("gpgpath", out gpgpath);
opts.TryGetValue("armor", out string armor);
useArmor = Boolean.TryParse(armor, out useArmor) && useArmor;
if (string.IsNullOrWhiteSpace(gpgkeyfile))
{
throw new ArgumentException("No gpgfile with encrypted credentials specified.");
}
if (!System.IO.File.Exists(gpgkeyfile))
{
throw new ArgumentException("Specified file with encrypted gpg credentials not found.");
}
LoadGPGKeyIdAndPassphrase();
if (gpgkeyid is null || gpgkeypassphrase is null)
{
throw new ArgumentException("Could not fetch gpg key id or gpg passphrase.");
}
gpgpath = gpgpath ?? Duplicati.Library.Encryption.GPGEncryption.GetGpgProgramPath();
SpawnGPG();
}
}
}
-130
View File
@@ -1,130 +0,0 @@
// Copyright (C) 2024, The Duplicati Team
// https://duplicati.com, hello@duplicati.com
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
using System;
using System.IO;
using System.Text.RegularExpressions;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
namespace UpdateVersionStamp
{
public static class Program
{
private static readonly string DIR_SEP = Path.DirectorySeparatorChar.ToString();
private static readonly Dictionary<string, Regex> FILEMAP;
static Program()
{
var versionre = @"(?<version>\d+\.\d+\.(\*|(\d+(\.(\*|\d+)))?))";
FILEMAP = new Dictionary<string, Regex>(StringComparer.InvariantCultureIgnoreCase);
FILEMAP.Add("UpgradeData.wxi", new Regex(@"\<\?define ProductVersion\=\""" + versionre + @"\"" \?\>"));
FILEMAP.Add("AssemblyRedirects.xml", new Regex(@"newVersion\=\""" + versionre + @"\"""));
FILEMAP.Add("index.html", new Regex(@"\?v\=" + versionre));
FILEMAP.Add("login.html", new Regex(@"\?v\=" + versionre));
FILEMAP.Add("app.js", new Regex(@"\?v\=" + versionre));
}
private class Options
{
public string sourcefolder = Path.GetFullPath(Environment.CurrentDirectory);
public string ignorefilter = null;
public string version = null;
public string versiontag = null;
public void Fixup()
{
sourcefolder = Duplicati.Library.Common.IO.Util.AppendDirSeparator(System.IO.Path.GetFullPath(sourcefolder.Replace("/", DIR_SEP)));
if (ignorefilter != null)
ignorefilter =ignorefilter.Replace("/", DIR_SEP);
}
}
public static void Main(string[] _args)
{
List<string> args = new List<string>(_args);
Dictionary<string, string> options = Duplicati.Library.Utility.CommandLineParser.ExtractOptions(args);
Options opt = new Options();
foreach (FieldInfo fi in opt.GetType().GetFields())
if (options.ContainsKey(fi.Name))
fi.SetValue(opt, options[fi.Name]);
opt.Fixup();
Duplicati.Library.Utility.IFilter filter = null;
if (!string.IsNullOrEmpty(opt.ignorefilter))
filter = new Duplicati.Library.Utility.FilterExpression(opt.ignorefilter, false);
Func<string, bool> isFile = (string x) => !x.EndsWith(DIR_SEP);
var paths = Duplicati.Library.Utility.Utility.EnumerateFileSystemEntries(opt.sourcefolder)
.Where(x => Duplicati.Library.Utility.FilterExpression.Matches(filter, x))
.Where(x => isFile(x) && FILEMAP.ContainsKey(Path.GetFileName(x)))
.Select(x =>
{
var m = FILEMAP[Path.GetFileName(x)].Match(File.ReadAllText(x));
return m.Success ?
new { File = x, Version = new Version(m.Groups["version"].Value.Replace("*", "0")), Display = m.Groups["version"].Value }
: null;
})
.Where(x => x != null)
.ToArray(); //No need to re-eval
if (paths.Count() == 0)
{
Console.WriteLine("No files found to update...");
return;
}
foreach (var p in paths)
Console.WriteLine("{0}\t:{1}", p.Display, p.File);
if (string.IsNullOrWhiteSpace(opt.version))
{
var maxv = paths.Select(x => x.Version).Max();
opt.version = new Version(
maxv.Major,
maxv.Minor,
maxv.Build,
maxv.Revision).ToString();
}
//Sanity check
var nv = new Version(opt.version).ToString(4);
foreach (var p in paths)
{
var re = FILEMAP[Path.GetFileName(p.File)];
var txt = File.ReadAllText(p.File);
//var m = re.Match(txt).Groups["version"];
txt = re.Replace(txt, (m) => {
var t = m.Groups["version"];
return m.Value.Replace(t.Value, nv);
});
File.WriteAllText(p.File, txt);
}
Console.WriteLine("Updated {0} files to version {1}", paths.Count(), opt.version);
}
}
}
@@ -1,19 +0,0 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<OutputType>Exe</OutputType>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\..\Duplicati\Library\Utility\Duplicati.Library.Utility.csproj" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.DotNet.Analyzers.Compatibility" Version="0.2.12-alpha">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
</ItemGroup>
</Project>
@@ -1,35 +0,0 @@
Microsoft Visual Studio Solution File, Format Version 11.00
# Visual Studio 2010
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "UpdateVersionStamp", "UpdateVersionStamp.csproj", "{1920C3B0-98A0-410F-8972-9C19FA616FE5}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Duplicati.Library.Utility", "..\..\Duplicati\Library\Utility\Duplicati.Library.Utility.csproj", "{DE3E5D4C-51AB-4E5E-BEE8-E636CEBFBA65}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Duplicati.Library.Common", "..\..\Duplicati\Library\Common\Duplicati.Library.Common.csproj", "{D63E53E4-A458-4C2F-914D-92F715F58ACF}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{1920C3B0-98A0-410F-8972-9C19FA616FE5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{1920C3B0-98A0-410F-8972-9C19FA616FE5}.Debug|Any CPU.Build.0 = Debug|Any CPU
{1920C3B0-98A0-410F-8972-9C19FA616FE5}.Release|Any CPU.ActiveCfg = Release|Any CPU
{1920C3B0-98A0-410F-8972-9C19FA616FE5}.Release|Any CPU.Build.0 = Release|Any CPU
{DE3E5D4C-51AB-4E5E-BEE8-E636CEBFBA65}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{DE3E5D4C-51AB-4E5E-BEE8-E636CEBFBA65}.Debug|Any CPU.Build.0 = Debug|Any CPU
{DE3E5D4C-51AB-4E5E-BEE8-E636CEBFBA65}.Release|Any CPU.ActiveCfg = Release|Any CPU
{DE3E5D4C-51AB-4E5E-BEE8-E636CEBFBA65}.Release|Any CPU.Build.0 = Release|Any CPU
{D63E53E4-A458-4C2F-914D-92F715F58ACF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{D63E53E4-A458-4C2F-914D-92F715F58ACF}.Debug|Any CPU.Build.0 = Debug|Any CPU
{D63E53E4-A458-4C2F-914D-92F715F58ACF}.Release|Any CPU.ActiveCfg = Release|Any CPU
{D63E53E4-A458-4C2F-914D-92F715F58ACF}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(MonoDevelopProperties) = preSolution
StartupItem = UpdateVersionStamp.csproj
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal
+6 -6
View File
@@ -186,9 +186,9 @@ public static partial class Command
EnvHelper.CopyDirectory(buildDir, binDir, recursive: true);
// Patch the plist and place the icon from the resources
var installerDir = Path.Combine(baseDir, "Installer", "MacOS");
var resourcesDir = Path.Combine(baseDir, "ReleaseBuilder", "Resources", "MacOS");
var plist = File.ReadAllText(Path.Combine(installerDir, "app-resources", "Info.plist"))
var plist = File.ReadAllText(Path.Combine(resourcesDir, "app-resources", "Info.plist"))
.Replace("!LONG_VERSION!", rtcfg.ReleaseInfo.ReleaseName)
.Replace("!SHORT_VERSION!", rtcfg.ReleaseInfo.Version.ToString());
@@ -198,21 +198,21 @@ public static partial class Command
);
File.Copy(
Path.Combine(installerDir, "app-resources", "Duplicati.icns"),
Path.Combine(resourcesDir, "app-resources", "Duplicati.icns"),
Path.Combine(tmpApp, "Contents", "Resources", "Duplicati.icns"),
overwrite: true
);
// Inject the launch agent
EnvHelper.CopyDirectory(
Path.Combine(installerDir, "daemon"),
Path.Combine(resourcesDir, "daemon"),
Path.Combine(tmpApp, "Contents", "Resources"),
recursive: true
);
// Inject the uninstall.sh script
File.Copy(
Path.Combine(installerDir, "uninstall.sh"),
Path.Combine(resourcesDir, "uninstall.sh"),
Path.Combine(tmpApp, "Contents", "MacOS", "uninstall.sh"),
overwrite: true
);
@@ -239,7 +239,7 @@ public static partial class Command
.Distinct()
.ToList();
var entitlementFile = Path.Combine(installerDir, "Entitlements.plist");
var entitlementFile = Path.Combine(resourcesDir, "Entitlements.plist");
foreach (var f in signtargets)
await rtcfg.Codesign(f, entitlementFile);
+30 -27
View File
@@ -240,8 +240,7 @@ public static partial class Command
/// <returns>A task representing the asynchronous operation.</returns>
static async Task BuildMsiPackage(string baseDir, string buildRoot, string msiFile, PackageTarget target, RuntimeConfig rtcfg)
{
var installerDir = Path.Combine(baseDir, "Installer", "Windows");
var binFiles = Path.Combine(installerDir, "binfiles.wxs");
var resourcesDir = Path.Combine(baseDir, "ReleaseBuilder", "Resources", "Windows");
var buildTmp = Path.Combine(buildRoot, "tmp-msi");
if (Directory.Exists(buildTmp))
@@ -254,6 +253,10 @@ public static partial class Command
if (!sourceFiles.EndsWith(Path.DirectorySeparatorChar))
sourceFiles += Path.DirectorySeparatorChar;
var binFiles = Path.Combine(resourcesDir, "binfiles.txt");
if (File.Exists(binFiles))
File.Delete(binFiles);
File.WriteAllText(binFiles, WixHeatBuilder.CreateWixFilelist(sourceFiles));
await ProcessHelper.Execute([
@@ -261,9 +264,9 @@ public static partial class Command
"--define", $"HarvestPath={sourceFiles}",
"--arch", target.ArchString,
"--output", msiFile,
Path.Combine(installerDir, "Shortcuts.wxs"),
Path.Combine(resourcesDir, "Shortcuts.wxs"),
binFiles,
Path.Combine(installerDir, "Duplicati.wxs")
Path.Combine(resourcesDir, "Duplicati.wxs")
], workingDirectory: buildRoot);
if (rtcfg.UseAuthenticodeSigning)
@@ -320,8 +323,8 @@ public static partial class Command
}
Directory.CreateDirectory(mountDir);
var installerDir = Path.Combine(baseDir, "Installer", "MacOS");
var compressedDmg = Path.Combine(installerDir, "template.dmg.bz2");
var resourcesDir = Path.Combine(baseDir, "ReleaseBuilder", "Resources", "MacOS");
var compressedDmg = Path.Combine(resourcesDir, "template.dmg.bz2");
if (!File.Exists(compressedDmg))
throw new FileNotFoundException($"Compressed dmg template file not found: {compressedDmg}");
@@ -358,7 +361,7 @@ public static partial class Command
// Place the prepared folder
EnvHelper.CopyDirectory(Path.Combine(buildRoot, $"{target.BuildTargetString}-{rtcfg.MacOSAppName}"), appFolder, recursive: true);
await PrepareAndReSignAppBundle(appFolder, installerDir, target, rtcfg);
await PrepareAndReSignAppBundle(appFolder, resourcesDir, target, rtcfg);
// Set permissions inside DMG file
if (!OperatingSystem.IsWindows())
@@ -375,7 +378,7 @@ public static partial class Command
Directory.Delete(mountDir, false);
if (rtcfg.UseCodeSignSigning)
await rtcfg.Codesign(dmgFile, Path.Combine(installerDir, "Entitlements.plist"));
await rtcfg.Codesign(dmgFile, Path.Combine(resourcesDir, "Entitlements.plist"));
}
/// <summary>
@@ -394,7 +397,7 @@ public static partial class Command
Directory.Delete(tmpFolder, true);
Directory.CreateDirectory(tmpFolder);
var installerDir = Path.Combine(baseDir, "Installer", "MacOS");
var installerDir = Path.Combine(baseDir, "ReleaseBuilder", "Resources", "MacOS");
var appFolder = Path.Combine(tmpFolder, rtcfg.MacOSAppName);
if (Directory.Exists(appFolder))
@@ -527,7 +530,7 @@ public static partial class Command
}
// Copy debian files
var installerDir = Path.Combine(baseDir, "Installer", "debian");
var resourcesDir = Path.Combine(baseDir, "ReleaseBuilder", "Resources", "debian");
// Write in the release notes
if (!string.IsNullOrEmpty(rtcfg.ChangelogNews))
@@ -536,7 +539,7 @@ public static partial class Command
// Write a custom changelog file
File.WriteAllText(
Path.Combine(pkgroot, "DEBIAN", "changelog"),
File.ReadAllText(Path.Combine(installerDir, "changelog.template.txt"))
File.ReadAllText(Path.Combine(resourcesDir, "changelog.template.txt"))
.Replace("%VERSION%", rtcfg.ReleaseInfo.Version.ToString())
.Replace("%DATE%", DateTime.UtcNow.ToString("ddd, dd MMM yyyy HH:mm:ss +0000", CultureInfo.InvariantCulture))
);
@@ -554,7 +557,7 @@ public static partial class Command
// Write a custom control file
File.WriteAllText(
Path.Combine(pkgroot, "DEBIAN", "control"),
File.ReadAllText(Path.Combine(installerDir, "control.template.txt"))
File.ReadAllText(Path.Combine(resourcesDir, "control.template.txt"))
.Replace("%VERSION%", rtcfg.ReleaseInfo.Version.ToString())
.Replace("%ARCH%", debArchString)
.Replace("%DEPENDS%", string.Join(", ", target.Interface == InterfaceType.GUI
@@ -563,14 +566,14 @@ public static partial class Command
);
// Install various helper files
var sharedDir = Path.Combine(baseDir, "Installer", "shared");
var sharedDir = Path.Combine(baseDir, "ReleaseBuilder", "Resources", "shared");
var supportFiles = new List<(string Source, string Destination)>{
(
Path.Combine(installerDir, "systemd", "duplicati.default"),
Path.Combine(resourcesDir, "systemd", "duplicati.default"),
Path.Combine(pkgroot, "etc", "default", "duplicati")
),
(
Path.Combine(installerDir, "systemd", "duplicati.service"),
Path.Combine(resourcesDir, "systemd", "duplicati.service"),
Path.Combine(pkgroot, "lib", "systemd", "system", "duplicati.service")
),
(
@@ -600,7 +603,7 @@ public static partial class Command
// Copy the Docker build file
File.Copy(
Path.Combine(installerDir, "Dockerfile.build"),
Path.Combine(resourcesDir, "Dockerfile.build"),
Path.Combine(debroot, "Dockerfile"),
true
);
@@ -641,7 +644,7 @@ public static partial class Command
/// <returns>A task representing the asynchronous operation.</returns>
static async Task BuildRpmPackage(string baseDir, string buildRoot, string rpmFile, PackageTarget target, RuntimeConfig rtcfg)
{
var installerDir = Path.Combine(baseDir, "Installer", "fedora");
var resourcesDir = Path.Combine(baseDir, "ReleaseBuilder", "Resources", "fedora");
var tmpbuild = Path.Combine(buildRoot, "tmp-fedora");
if (Directory.Exists(tmpbuild))
Directory.Delete(tmpbuild, true);
@@ -667,13 +670,13 @@ public static partial class Command
File.Move(tarfile, Path.Combine(sources, Path.GetFileName(tarfile)));
// Move in extra files for building
var sharedDir = Path.Combine(baseDir, "Installer", "shared");
var sharedDir = Path.Combine(baseDir, "ReleaseBuilder", "Resources", "shared");
File.Copy(Path.Combine(sharedDir, "pixmaps", "duplicati.xpm"), Path.Combine(sources, "duplicati.xpm"));
File.Copy(Path.Combine(sharedDir, "pixmaps", "duplicati.png"), Path.Combine(sources, "duplicati.png"));
File.Copy(Path.Combine(sharedDir, "desktop", "duplicati.desktop"), Path.Combine(sources, "duplicati.desktop"));
File.Copy(Path.Combine(installerDir, "systemd", "duplicati.service"), Path.Combine(sources, "duplicati.service"));
File.Copy(Path.Combine(installerDir, "systemd", "duplicati.default"), Path.Combine(sources, "duplicati.default"));
File.Copy(Path.Combine(installerDir, "duplicati-install-recursive.sh"), Path.Combine(sources, "duplicati-install-recursive.sh"));
File.Copy(Path.Combine(resourcesDir, "systemd", "duplicati.service"), Path.Combine(sources, "duplicati.service"));
File.Copy(Path.Combine(resourcesDir, "systemd", "duplicati.default"), Path.Combine(sources, "duplicati.default"));
File.Copy(Path.Combine(resourcesDir, "duplicati-install-recursive.sh"), Path.Combine(sources, "duplicati-install-recursive.sh"));
var executables = ExecutableRenames.AsEnumerable();
if (target.Interface == InterfaceType.Cli)
@@ -682,7 +685,7 @@ public static partial class Command
// Write custom script to install executable files
File.WriteAllLines(
Path.Combine(sources, "duplicati-install-binaries.sh"),
File.ReadAllLines(Path.Combine(installerDir, "duplicati-install-binaries.sh"))
File.ReadAllLines(Path.Combine(resourcesDir, "duplicati-install-binaries.sh"))
.SelectMany(line =>
{
if (line.StartsWith("REPL: "))
@@ -701,7 +704,7 @@ public static partial class Command
File.WriteAllText(
Path.Combine(sources, "duplicati.spec"),
File.ReadAllText(Path.Combine(installerDir, "duplicati.spec.template.txt"))
File.ReadAllText(Path.Combine(resourcesDir, "duplicati.spec.template.txt"))
.Replace("%BUILDDATE%", DateTime.UtcNow.ToString("yyyyMMdd"))
.Replace("%BUILDVERSION%", rtcfg.ReleaseInfo.Version.ToString())
.Replace("%BUILDTAG%", rtcfg.ReleaseInfo.Channel.ToString().ToLowerInvariant())
@@ -715,7 +718,7 @@ public static partial class Command
// Install the Docker build file
File.Copy(
Path.Combine(installerDir, "Dockerfile.build"),
Path.Combine(resourcesDir, "Dockerfile.build"),
Path.Combine(tmpbuild, "Dockerfile"),
true
);
@@ -731,7 +734,7 @@ public static partial class Command
// This is required because rpmbuild reads file mode
// in a way that is not compatible with Docker desktop bind mounts
File.Copy(
Path.Combine(installerDir, "inside-docker.sh"),
Path.Combine(resourcesDir, "inside-docker.sh"),
Path.Combine(tmpbuild, "inside-docker.sh"),
true
);
@@ -768,7 +771,7 @@ public static partial class Command
/// <returns>A task representing the asynchronous operation.</returns>
private static async Task BuildDockerImages(string baseDir, string buildRoot, IEnumerable<PackageTarget> targets, RuntimeConfig rtcfg)
{
var installerDir = Path.Combine(baseDir, "Installer", "Docker");
var resourcesDir = Path.Combine(baseDir, "ReleaseBuilder", "Resources", "Docker");
var dockerArchs = targets.Select(target => target switch
{
PackageTarget { Arch: ArchType.x64, OS: OSType.Linux, Interface: InterfaceType.Cli } => "linux/amd64",
@@ -820,7 +823,7 @@ public static partial class Command
"--platform", string.Join(",", dockerArchs),
"--build-arg", $"VERSION={rtcfg.ReleaseInfo.Version}",
"--build-arg", $"CHANNEL={rtcfg.ReleaseInfo.Channel.ToString().ToLowerInvariant()}",
"--file", Path.Combine(installerDir, "Dockerfile"),
"--file", Path.Combine(resourcesDir, "Dockerfile"),
"--output", $"type=image,push={rtcfg.PushToDocker.ToString().ToLowerInvariant()}",
"."
]);
+1 -1
View File
@@ -18,7 +18,7 @@ public static partial class Command
// Add modified files
await ProcessHelper.Execute(new[] {
"git", "add",
"Updates/build_version.txt",
"ReleaseBuilder/build_version.txt",
"changelog.txt"
}, workingDirectory: baseDir);
+2 -2
View File
@@ -345,7 +345,7 @@ public static partial class Command
}
var baseDir = Path.GetDirectoryName(input.SolutionFile.FullName) ?? throw new Exception("Path to solution file was invalid");
var versionFilePath = Path.Combine(baseDir, "Updates", "build_version.txt");
var versionFilePath = Path.Combine(baseDir, "ReleaseBuilder", "build_version.txt");
if (!File.Exists(versionFilePath))
throw new FileNotFoundException($"Version file not found: {versionFilePath}");
@@ -596,7 +596,7 @@ public static partial class Command
regex.Replace(File.ReadAllText(file), $"?v={releaseInfo.Version}")
);
var wixFile = Path.Combine(baseDir, "Installer", "Windows", "UpgradeData.wxi");
var wixFile = Path.Combine(baseDir, "ReleaseBuilder", "Resources", "Windows", "UpgradeData.wxi");
File.WriteAllText(
wixFile,
Regex.Replace(

Before

Width:  |  Height:  |  Size: 601 KiB

After

Width:  |  Height:  |  Size: 601 KiB

Before

Width:  |  Height:  |  Size: 112 KiB

After

Width:  |  Height:  |  Size: 112 KiB

@@ -3,7 +3,7 @@
<?define UpgradeCode="1c94bc5a-2bf2-4273-9d8f-2cb30e780d16" ?>
<!-- Remember to change product version on each install -->
<?define ProductVersion="2.0.0.7" ?>
<?define ProductVersion="2.0.8.106" ?>
<?define Manufacturer="Duplicati Team" ?>
File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 579 B

After

Width:  |  Height:  |  Size: 579 B

Before

Width:  |  Height:  |  Size: 2.0 KiB

After

Width:  |  Height:  |  Size: 2.0 KiB

-76
View File
@@ -1,76 +0,0 @@
RELEASE_TIMESTAMP=$(date +%Y-%m-%d)
RELEASE_INC_VERSION=$(cat Updates/build_version.txt)
RELEASE_INC_VERSION=$((RELEASE_INC_VERSION+1))
RELEASE_NAME=2.0_CLI_experimental_${RELEASE_TIMESTAMP}
RELEASE_CHANGEINFO=$(cat Updates/debug_changeinfo.txt)
RELEASE_VERSION="2.0.0.${RELEASE_INC_VERSION}"
UPDATE_ZIP_URLS=http://updates.duplicati.com/debug/duplicati.zip\;http://alt.updates.duplicati.com/debug/duplicati.zip
UPDATE_MANIFEST_URLS=http://updates.duplicati.com/debug/latest.manifest\;http://alt.updates.duplicati.com/debug/latest.manifest
UPDATER_KEYFILE=/Users/kenneth/Dropbox/Privat/Duplicati-updater-debug.key
if [ "x${RELEASE_CHANGEINFO}" == "x" ]; then
echo "No information in changeinfo file"
exit 0
fi
echo -n "Enter keyfile password: "
read -s KEYFILE_PASSWORD
echo
echo "${RELEASE_NAME}" > Duplicati/License/VersionTag.txt
echo "${UPDATE_MANIFEST_URLS}" > Duplicati/Library/AutoUpdater/AutoUpdateURL.txt
cp "Updates/debug_key.txt" Duplicati/Library/AutoUpdater/AutoUpdateSignKeys.txt
rm -rf Duplicati/GUI/Duplicati.GUI.TrayIcon/bin/Debug
mono BuildTools/UpdateVersionStamp/bin/Debug/UpdateVersionStamp.exe --version="${RELEASE_VERSION}"
xbuild /p:Configuration=Debug BuildTools/AutoUpdateBuilder/AutoUpdateBuilder.sln
xbuild /p:Configuration=Debug Duplicati.sln
BUILD_STATUS=$?
if [ "${BUILD_STATUS}" -ne 0 ]; then
echo "Failed to build, xbuild gave ${BUILD_STATUS}, exiting"
exit 4
fi
if [ ! -d "Updates/build" ]; then mkdir "Updates/build"; fi
UPDATE_SOURCE=Updates/build/debug_source-${RELEASE_VERSION}
UPDATE_TARGET=Updates/build/debug_target-${RELEASE_VERSION}
if [ -e "${UPDATE_SOURCE}" ]; then rm -rf "${UPDATE_SOURCE}"; fi
if [ -e "${UPDATE_TARGET}" ]; then rm -rf "${UPDATE_TARGET}"; fi
mkdir "${UPDATE_SOURCE}"
mkdir "${UPDATE_TARGET}"
cp -R Duplicati/GUI/Duplicati.GUI.TrayIcon/bin/Debug/* "${UPDATE_SOURCE}"
cp -R Duplicati/Server/webroot "${UPDATE_SOURCE}"
if [ -e "${UPDATE_SOURCE}/control_dir" ]; then rm -rf "${UPDATE_SOURCE}/control_dir"; fi
if [ -e "${UPDATE_SOURCE}/Duplicati-server.sqlite" ]; then rm "${UPDATE_SOURCE}/Duplicati-server.sqlite"; fi
if [ -e "${UPDATE_SOURCE}/Duplicati.debug.log" ]; then rm "${UPDATE_SOURCE}/Duplicati.debug.log"; fi
if [ -e "${UPDATE_SOURCE}/updates" ]; then rm -rf "${UPDATE_SOURCE}/updates"; fi
rm -rf "${UPDATE_SOURCE}/"*.mdb;
rm -rf "${UPDATE_SOURCE}/"*.pdb;
echo
echo "Building signed package ..."
mono BuildTools/AutoUpdateBuilder/bin/Debug/AutoUpdateBuilder.exe --input="${UPDATE_SOURCE}" --output="${UPDATE_TARGET}" --keyfile="${UPDATER_KEYFILE}" --manifest=Updates/debug.manifest --changeinfo="${RELEASE_CHANGEINFO}" --displayname="${RELEASE_NAME}" --remoteurls="${UPDATE_ZIP_URLS}" --version="${RELEASE_VERSION}" --keyfile-password="$KEYFILE_PASSWORD"
echo "${RELEASE_INC_VERSION}" > "Updates/build_version.txt"
mv "${UPDATE_TARGET}/package.zip" "${UPDATE_TARGET}/duplicati.zip"
mv "${UPDATE_TARGET}/autoupdate.manifest" "${UPDATE_TARGET}/latest.manifest"
mono BuildTools/UpdateVersionStamp/bin/Debug/UpdateVersionStamp.exe --version="2.0.0.7"
echo
echo "Built DEBUG version: ${RELEASE_VERSION} - ${RELEASE_NAME}"
echo " in folder: ${UPDATE_TARGET}"
-357
View File
@@ -1,357 +0,0 @@
#!/bin/bash
if [ ! -f "$1" ]
then
echo "Please supply the path to an existing zip binary as the first argument"
exit 1
fi
while true
do
DOCKER_RESULT=$(docker ps)
if [ "$?" != "0" ]
then
echo "It appears the Docker daemon is not running, make sure you started it"
read -p "Press [Enter] key to AFTER you started Docker"
continue
fi
break
done
GITHUB_TOKEN_FILE="${HOME}/.config/github-api-token"
GPG_KEYFILE="${HOME}/.config/signkeys/Duplicati/updater-gpgkey.key"
AUTHENTICODE_PFXFILE="${HOME}/.config/signkeys/Duplicati/authenticode.pfx"
AUTHENTICODE_PASSWORD="${HOME}/.config/signkeys/Duplicati/authenticode.key"
MONO=/Library/Frameworks/Mono.framework/Commands/mono
VBOX_USER=IEUser@192.168.56.102
S3_BUCKET_NAME="updates.duplicati.com"
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)
BUILDTAG_RAW=$(echo "${ZIPFILE}" | cut -d "." -f 1-4 | cut -d "-" -f 2-4)
BUILDTAG="${BUILDTAG_RAW//-}"
RPMNAME="duplicati-${VERSION}-${BUILDTAG}.noarch.rpm"
DEBNAME="duplicati_${VERSION}-1_all.deb"
MSI64NAME="duplicati-${BUILDTAG_RAW}-x64.msi"
MSI32NAME="duplicati-${BUILDTAG_RAW}-x86.msi"
DMGNAME="duplicati-${BUILDTAG_RAW}.dmg"
PKGNAME="duplicati-${BUILDTAG_RAW}.pkg"
SPKNAME="duplicati-${BUILDTAG_RAW}.spk"
SIGNAME="duplicati-${BUILDTAG_RAW}-signatures.zip"
UPDATE_TARGET="Updates/build/${BUILDTYPE}_target-${VERSION}"
echo "Filename: ${ZIPFILE}"
echo "Version: ${VERSION}"
echo "Buildtype: ${BUILDTYPE}"
echo "Buildtag: ${BUILDTAG}"
echo "RPMName: ${RPMNAME}"
echo "DEBName: ${DEBNAME}"
echo "SPKName: ${SPKNAME}"
build_file_signatures() {
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"
shasum -a 1 "$1" | awk -F ' ' '{print $1}' > "$2.sha1"
shasum -a 256 "$1" | awk -F ' ' '{print $1}' > "$2.sha256"
}
if [ -f "${GPG_KEYFILE}" ]; then
if [ "z${KEYFILE_PASSWORD}" == "z" ]; then
echo -n "Enter keyfile password: "
read -s KEYFILE_PASSWORD
echo
fi
GPGDATA=$("${MONO}" "BuildTools/AutoUpdateBuilder/bin/Debug/SharpAESCrypt.exe" d "${KEYFILE_PASSWORD}" "${GPG_KEYFILE}")
if [ ! $? -eq 0 ]; then
echo "Decrypting GPG keyfile failed"
exit 1
fi
GPGID=$(echo "${GPGDATA}" | head -n 1)
GPGKEY=$(echo "${GPGDATA}" | head -n 2 | tail -n 1)
else
echo "No GPG keyfile found, skipping gpg signatures"
fi
# Pre-boot virtual machine
echo "Booting Win10 build instance"
VBoxHeadless --startvm Duplicati-Win10-Build &
# Then do the local build to mask the waiting a little more
echo ""
echo ""
echo "Building OSX package locally ..."
echo ""
echo "Enter local sudo password..."
cd "Installer/OSX"
bash "make-dmg.sh" "../../$1"
mv "Duplicati.dmg" "../../${UPDATE_TARGET}/${DMGNAME}"
mv "Duplicati.pkg" "../../${UPDATE_TARGET}/${PKGNAME}"
cd "../.."
echo ""
echo ""
echo "Building Synology package locally ..."
cd Installer/Synology
bash "make-binary-package.sh" "../../$1"
mv "${SPKNAME}" "../../${UPDATE_TARGET}/"
cd ../..
echo ""
echo ""
echo "Building Debian deb with Docker ..."
cd "Installer/debian"
bash "docker-build-binary.sh" "../../$1"
cd "../.."
mv "Installer/debian/${DEBNAME}" "${UPDATE_TARGET}"
echo "Done building deb package"
echo ""
echo ""
echo "Building Fedora RPM with Docker ..."
cd "Installer/fedora"
bash "docker-build-binary.sh" "../../$1"
cd "../.."
mv "Installer/fedora/${RPMNAME}" "${UPDATE_TARGET}"
echo "Done building rpm package"
echo ""
echo ""
echo "Building Docker images ..."
cd Installer/Docker
bash build-images.sh ../../$1
cd ../..
echo "Done building Docker images"
echo ""
echo ""
echo "Building Windows instance in virtual machine"
while true
do
ssh -o ConnectTimeout=5 ${VBOX_USER} "dir"
if [ $? -eq 255 ]; then
echo "Windows Build machine is not responding, try restarting it"
read -p "Press [Enter] key to try again"
continue
fi
break
done
cat > "tmp-windows-commands.bat" <<EOF
SET VS120COMNTOOLS=%VS140COMNTOOLS%
cd \\Duplicati\\Installer\\Windows
build-msi.bat "../../$1"
EOF
ssh ${VBOX_USER} "\\Duplicati\\tmp-windows-commands.bat"
ssh ${VBOX_USER} "shutdown /s /t 0"
rm "tmp-windows-commands.bat"
mv "./Installer/Windows/Duplicati.msi" "${UPDATE_TARGET}/${MSI64NAME}"
mv "./Installer/Windows/Duplicati-32bit.msi" "${UPDATE_TARGET}/${MSI32NAME}"
if [ -f "${AUTHENTICODE_PFXFILE}" ] && [ -f "${AUTHENTICODE_PASSWORD}" ]; then
echo "Performing authenticode signing of installers"
if [ "z${KEYFILE_PASSWORD}" == "z" ]; then
echo -n "Enter keyfile password: "
read -s KEYFILE_PASSWORD
echo
fi
authenticode_sign() {
NEST=""
for hashalg in sha1 sha256; do
SIGN_MSG=$(osslsigncode sign -pkcs12 "${AUTHENTICODE_PFXFILE}" -pass "${PFX_PASS}" -n "Duplicati" -i "http://www.duplicati.com" -h "${hashalg}" ${NEST} -t "http://timestamp.digicert.com?alg=${hashalg}" -in "$1" -out tmpfile)
if [ "${SIGN_MSG}" != "Succeeded" ]; then echo "${SIGN_MSG}"; fi
mv tmpfile "$1"
NEST="-nest"
done
}
PFX_PASS=$("${MONO}" "BuildTools/AutoUpdateBuilder/bin/Debug/SharpAESCrypt.exe" d "${KEYFILE_PASSWORD}" "${AUTHENTICODE_PASSWORD}")
DECRYPT_STATUS=$?
if [ "${DECRYPT_STATUS}" -ne 0 ]; then
echo "Failed to decrypt, SharpAESCrypt gave status ${DECRYPT_STATUS}, exiting"
exit 4
fi
if [ "x${PFX_PASS}" == "x" ]; then
echo "Failed to decrypt, SharpAESCrypt gave empty password, exiting"
exit 4
fi
authenticode_sign "${UPDATE_TARGET}/${MSI64NAME}"
authenticode_sign "${UPDATE_TARGET}/${MSI32NAME}"
else
echo "Skipped authenticode signing as files are missing"
fi
echo ""
echo ""
echo "Performing macOS notarization ..."
# Notarize and staple, cannot run in parallel but takes a while
xcrun notarytool submit "${UPDATE_TARGET}/${DMGNAME}" --keychain-profile "duplicati-notarize" --wait
xcrun notarytool submit "${UPDATE_TARGET}/${PKGNAME}" --keychain-profile "duplicati-notarize" --wait
xcrun stapler staple "${UPDATE_TARGET}/${DMGNAME}"
xcrun stapler staple "${UPDATE_TARGET}/${PKGNAME}"
echo ""
echo ""
echo "Done building, uploading installers ..."
if [ -d "./tmp" ]; then
rm -rf "./tmp"
fi
mkdir "./tmp"
echo "{" > "./tmp/latest-installers.json"
process_installer() {
if [ "$2" != "zip" ]; then
aws --profile=duplicati-upload s3 cp "${UPDATE_TARGET}/$1" "s3://${S3_BUCKET_NAME}/${BUILDTYPE}/$1"
fi
local MD5=$(md5 ${UPDATE_TARGET}/$1 | awk -F ' ' '{print $NF}')
local SHA1=$(shasum -a 1 ${UPDATE_TARGET}/$1 | awk -F ' ' '{print $1}')
local SHA256=$(shasum -a 256 ${UPDATE_TARGET}/$1 | awk -F ' ' '{print $1}')
cat >> "./tmp/latest-installers.json" <<EOF
"$2": {
"name": "$1",
"url": "https://updates.duplicati.com/${BUILDTYPE}/$1",
"md5": "${MD5}",
"sha1": "${SHA1}",
"sha256": "${SHA256}"
},
EOF
}
process_installer "${ZIPFILE}" "zip"
process_installer "${SPKNAME}" "spk"
process_installer "${RPMNAME}" "rpm"
process_installer "${DEBNAME}" "deb"
process_installer "${DMGNAME}" "dmg"
process_installer "${PKGNAME}" "pkg"
process_installer "${MSI32NAME}" "msi86"
process_installer "${MSI64NAME}" "msi64"
cat >> "./tmp/latest-installers.json" <<EOF
"version": "${VERSION}"
}
EOF
echo "duplicati_installers =" > "./tmp/latest-installers.js"
cat "./tmp/latest-installers.json" >> "./tmp/latest-installers.js"
echo ";" >> "./tmp/latest-installers.js"
aws --profile=duplicati-upload s3 cp "./tmp/latest-installers.json" "s3://${S3_BUCKET_NAME}/${BUILDTYPE}/latest-installers.json"
aws --profile=duplicati-upload s3 cp "./tmp/latest-installers.js" "s3://${S3_BUCKET_NAME}/${BUILDTYPE}/latest-installers.js"
if [ -d "./tmp" ]; then
rm -rf "./tmp"
fi
SIG_FOLDER="duplicati-${BUILDTAG_RAW}-signatures"
mkdir tmp
mkdir "./tmp/${SIG_FOLDER}"
for FILE in "${SPKNAME}" "${RPMNAME}" "${DEBNAME}" "${DMGNAME}" "${PKGNAME}" "${MSI32NAME}" "${MSI64NAME}" "${ZIPFILE}"; do
build_file_signatures "${UPDATE_TARGET}/${FILE}" "./tmp/${SIG_FOLDER}/${FILE}"
done
if [ "z${GPGID}" != "z" ]; then
echo "${GPGID}" > "./tmp/${SIG_FOLDER}/sign-key.txt"
echo "https://pgp.mit.edu/pks/lookup?op=get&search=${GPGID}" >> "./tmp/${SIG_FOLDER}/sign-key.txt"
fi
if [ -f "${UPDATE_TARGET}/${SIGNAME}" ]; then
rm "${UPDATE_TARGET}/${SIGNAME}"
fi
cd tmp
zip -r9 "./${SIGNAME}" "./${SIG_FOLDER}/"
cd ..
mv "./tmp/${SIGNAME}" "${UPDATE_TARGET}/${SIGNAME}"
rm -rf "./tmp/${SIG_FOLDER}"
aws --profile=duplicati-upload s3 cp "${UPDATE_TARGET}/${SIGNAME}" "s3://${S3_BUCKET_NAME}/${BUILDTYPE}/${SIGNAME}"
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
echo "Uploading files to Github release"
for FILE in "${SPKNAME}" "${RPMNAME}" "${DEBNAME}" "${DMGNAME}" "${PKGNAME}" "${MSI32NAME}" "${MSI64NAME}" "${SIGNAME}" "${ZIPFILE}"; do
github-release upload \
--tag "v${VERSION}-${BUILDTAG_RAW}" \
--name "${FILE}" \
--repo "duplicati" \
--user "duplicati" \
--security-token "${GITHUB_TOKEN}" \
--file "${UPDATE_TARGET}/${FILE}"
done
fi
rm -rf "./tmp"
if [ -f ~/.config/duplicati-mirror-sync.sh ]; then
bash ~/.config/duplicati-mirror-sync.sh
else
echo "Skipping CDN update"
fi
VBoxManage controlvm "Duplicati-Win10-Build" poweroff
-424
View File
@@ -1,424 +0,0 @@
RELEASE_TIMESTAMP=$(date +%Y-%m-%d)
RELEASE_INC_VERSION=$(cat Updates/build_version.txt)
RELEASE_INC_VERSION=$((RELEASE_INC_VERSION+1))
if [ "x$1" == "x" ]; then
RELEASE_TYPE="canary"
echo "No release type specified, using ${RELEASE_TYPE}"
else
RELEASE_TYPE=$1
fi
RELEASE_VERSION="2.0.8.${RELEASE_INC_VERSION}"
RELEASE_NAME="${RELEASE_VERSION}_${RELEASE_TYPE}_${RELEASE_TIMESTAMP}"
RELEASE_CHANGELOG_FILE="changelog.txt"
RELEASE_CHANGELOG_NEWS_FILE="changelog-news.txt"
RELEASE_FILE_NAME="duplicati-${RELEASE_NAME}"
GIT_STASH_NAME="auto-build-${RELEASE_TIMESTAMP}"
S3_BUCKET_NAME="updates.duplicati.com"
UPDATE_ZIP_URLS="https://updates.duplicati.com/${RELEASE_TYPE}/${RELEASE_FILE_NAME}.zip;https://alt.updates.duplicati.com/${RELEASE_TYPE}/${RELEASE_FILE_NAME}.zip"
UPDATE_MANIFEST_URLS="https://updates.duplicati.com/${RELEASE_TYPE}/latest.manifest;https://alt.updates.duplicati.com/${RELEASE_TYPE}/latest.manifest"
UPDATER_KEYFILE="${HOME}/.config/signkeys/Duplicati/updater-release.key"
GPG_KEYFILE="${HOME}/.config/signkeys/Duplicati/updater-gpgkey.key"
AUTHENTICODE_PFXFILE="${HOME}/.config/signkeys/Duplicati/authenticode.pfx"
AUTHENTICODE_PASSWORD="${HOME}/.config/signkeys/Duplicati/authenticode.key"
GITHUB_TOKEN_FILE="${HOME}/.config/github-api-token"
DISCOURSE_TOKEN_FILE="${HOME}/.config/discourse-api-token"
XBUILD=/Library/Frameworks/Mono.framework/Commands/msbuild
NUGET=/Library/Frameworks/Mono.framework/Commands/nuget
MONO=/Library/Frameworks/Mono.framework/Commands/mono
XAMARIN=/Library/Frameworks/Xamarin.Mac.framework
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)
if [ ! -f "$GPG" ]; then
echo "gpg executable not found: $GPG"
exit 1
fi
if [ ! -f "$XBUILD" ]; then
echo "xbuild/msbuild executable not found: $XBUILD"
exit 1
fi
if [ ! -f "$MONO" ]; then
echo "mono executable not found: $MONO"
exit 1
fi
if [ ! -f "$NUGET" ]; then
echo "NuGet executable not found: $NUGET"
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=""
elif [ "${RELEASE_TYPE}" == "canary" ]; then
OTHER_UPLOADS="nightly"
elif [ "${RELEASE_TYPE}" == "experimental" ]; then
OTHER_UPLOADS="nightly canary"
elif [ "${RELEASE_TYPE}" == "beta" ]; then
OTHER_UPLOADS="experimental canary nightly"
elif [ "${RELEASE_TYPE}" == "stable" ]; then
OTHER_UPLOADS="beta experimental canary nightly"
else
echo "Unsupported release type: ${RELEASE_TYPE}, supported types are: nightly, canary, experimental, beta, stable"
exit 0
fi
if [ ! -f "${RELEASE_CHANGELOG_FILE}" ]; then
echo "Changelog file is missing..."
exit 0
fi
if [ ! -f "${RELEASE_CHANGELOG_NEWS_FILE}" ]; then
echo "No updates to changelog file found"
echo
echo "To make a build without changelog news, run:"
echo " touch ""${RELEASE_CHANGELOG_NEWS_FILE}"" "
exit 0
fi
echo -n "Enter keyfile password: "
read -s KEYFILE_PASSWORD
echo
if [ "z${KEYFILE_PASSWORD}" == "z" ]; then
echo "No password entered, quitting"
exit 0
fi
echo "Activating sudo rights for building the installers later, please enter sudo password:"
sudo echo "Sudo activated"
RELEASE_CHANGEINFO_NEWS=$(cat "${RELEASE_CHANGELOG_NEWS_FILE}")
git stash save "${GIT_STASH_NAME}"
git pull
if [ ! "x${RELEASE_CHANGEINFO_NEWS}" == "x" ]; then
echo "${RELEASE_TIMESTAMP} - ${RELEASE_NAME}" > "tmp_changelog.txt"
echo "==========" >> "tmp_changelog.txt"
echo "${RELEASE_CHANGEINFO_NEWS}" >> "tmp_changelog.txt"
echo >> "tmp_changelog.txt"
cat "${RELEASE_CHANGELOG_FILE}" >> "tmp_changelog.txt"
cp "tmp_changelog.txt" "${RELEASE_CHANGELOG_FILE}"
rm "tmp_changelog.txt"
fi
echo "${RELEASE_NAME}" > "Duplicati/License/VersionTag.txt"
echo "${RELEASE_TYPE}" > "Duplicati/Library/AutoUpdater/AutoUpdateBuildChannel.txt"
echo "${UPDATE_MANIFEST_URLS}" > "Duplicati/Library/AutoUpdater/AutoUpdateURL.txt"
cp "Updates/release_key.txt" "Duplicati/Library/AutoUpdater/AutoUpdateSignKeys.txt"
RELEASE_CHANGEINFO=$(cat ${RELEASE_CHANGELOG_FILE})
if [ "x${RELEASE_CHANGEINFO}" == "x" ]; then
echo "No information in changeinfo file"
exit 0
fi
rm -rf "Duplicati/GUI/Duplicati.GUI.TrayIcon/bin/Release"
"${NUGET}" restore "BuildTools/UpdateVersionStamp/UpdateVersionStamp.sln"
"${XBUILD}" /property:Configuration=Release "BuildTools/UpdateVersionStamp/UpdateVersionStamp.sln"
"${MONO}" "BuildTools/UpdateVersionStamp/bin/Release/UpdateVersionStamp.exe" --version="${RELEASE_VERSION}"
"${NUGET}" restore "BuildTools/AutoUpdateBuilder/AutoUpdateBuilder.sln"
"${NUGET}" restore "BuildTools/GnupgSigningTool/GnupgSigningTool.sln"
"${NUGET}" restore "Duplicati.sln"
"${XBUILD}" /p:Configuration=Debug "BuildTools/AutoUpdateBuilder/AutoUpdateBuilder.sln"
"${XBUILD}" /p:Configuration=Debug "BuildTools/GnupgSigningTool/GnupgSigningTool.sln"
"${XBUILD}" /p:Configuration=Release /p:Version=${RELEASE_VERSION} /target:Clean "Duplicati.sln"
find "Duplicati" -type d -name "Release" | xargs rm -rf
if [ ! -d "$XAMARIN" ]; then
read -p"Warning, this build will not enable tray icon on Mac, hit any key to continue."
"${XBUILD}" /p:DefineConstants=ENABLE_GTK /p:Configuration=Release /p:Version=${RELEASE_VERSION} "Duplicati.sln"
else
"${XBUILD}" -p:DefineConstants=\"ENABLE_GTK\;XAMARIN_MAC\" /p:Configuration=Release /p:Version=${RELEASE_VERSION} "Duplicati.sln"
fi
BUILD_STATUS=$?
if [ "${BUILD_STATUS}" -ne 0 ]; then
echo "Failed to build, xbuild gave ${BUILD_STATUS}, exiting"
exit 4
fi
if [ ! -d "Updates/build" ]; then mkdir "Updates/build"; fi
UPDATE_SOURCE=Updates/build/${RELEASE_TYPE}_source-${RELEASE_VERSION}
UPDATE_TARGET=Updates/build/${RELEASE_TYPE}_target-${RELEASE_VERSION}
if [ -e "${UPDATE_SOURCE}" ]; then rm -rf "${UPDATE_SOURCE}"; fi
if [ -e "${UPDATE_TARGET}" ]; then rm -rf "${UPDATE_TARGET}"; fi
mkdir "${UPDATE_SOURCE}"
mkdir "${UPDATE_TARGET}"
cp -R Duplicati/GUI/Duplicati.GUI.TrayIcon/bin/Release/* "${UPDATE_SOURCE}"
cp -R Duplicati/Server/webroot "${UPDATE_SOURCE}"
# We copy some files for alphavss manually as they are not picked up by xbuild
mkdir "${UPDATE_SOURCE}/alphavss"
for FN in Duplicati/Library/Snapshots/bin/Release/AlphaVSS.*.dll; do
cp "${FN}" "${UPDATE_SOURCE}/alphavss/"
done
# Fix for some support libraries not being picked up
for BACKEND in Duplicati/Library/Backend/*; do
if [ -d "${BACKEND}/bin/Release/" ]; then
cp "${BACKEND}/bin/Release/"*.dll "${UPDATE_SOURCE}"
fi
done
# Install the assembly redirects for all Duplicati .exe files
find "${UPDATE_SOURCE}" -type f -name Duplicati.*.exe -maxdepth 1 -exec cp Installer/AssemblyRedirects.xml {}.config \;
# Clean some unwanted build files
for FILE in "control_dir" "Duplicati-server.sqlite" "Duplicati.debug.log" "updates"; do
if [ -e "${UPDATE_SOURCE}/${FILE}" ]; then rm -rf "${UPDATE_SOURCE}/${FILE}"; fi
done
# Clean the localization spam from Azure
for FILE in "de" "es" "fr" "it" "ja" "ko" "ru" "zh-Hans" "zh-Hant"; do
if [ -e "${UPDATE_SOURCE}/${FILE}" ]; then rm -rf "${UPDATE_SOURCE}/${FILE}"; fi
done
# Clean debug files, if any
rm -rf "${UPDATE_SOURCE}/"*.mdb;
rm -rf "${UPDATE_SOURCE}/"*.pdb;
# Remove all library docs files
rm -rf "${UPDATE_SOURCE}/"*.xml;
# Remove all .DS_Store and Thumbs.db files
find . -type f -name ".DS_Store" | xargs rm -rf
find . -type f -name "Thumbs.db" | xargs rm -rf
# Sign all files with Authenticode
if [ -f "${AUTHENTICODE_PFXFILE}" ] && [ -f "${AUTHENTICODE_PASSWORD}" ]; then
echo "Performing authenticode signing of executables and libraries"
authenticode_sign() {
NEST=""
for hashalg in sha1 sha256; do
SIGN_MSG=$(osslsigncode sign -pkcs12 "${AUTHENTICODE_PFXFILE}" -pass "${PFX_PASS}" -n "Duplicati" -i "http://www.duplicati.com" -h "${hashalg}" ${NEST} -t "http://timestamp.digicert.com?alg=${hashalg}" -in "$1" -out tmpfile)
if [ "${SIGN_MSG}" != "Succeeded" ]; then echo "${SIGN_MSG}"; fi
mv tmpfile "$1"
NEST="-nest"
done
}
PFX_PASS=$("${MONO}" "BuildTools/AutoUpdateBuilder/bin/Debug/SharpAESCrypt.exe" d "${KEYFILE_PASSWORD}" "${AUTHENTICODE_PASSWORD}")
DECRYPT_STATUS=$?
if [ "${DECRYPT_STATUS}" -ne 0 ]; then
echo "Failed to decrypt, SharpAESCrypt gave status ${DECRYPT_STATUS}, exiting"
exit 4
fi
if [ "x${PFX_PASS}" == "x" ]; then
echo "Failed to decrypt, SharpAESCrypt gave empty password, exiting"
exit 4
fi
for exec in "${UPDATE_SOURCE}/Duplicati."*.exe; do
authenticode_sign "${exec}"
done
for exec in "${UPDATE_SOURCE}/Duplicati."*.dll; do
authenticode_sign "${exec}"
done
else
echo "Skipped authenticode signing as files are missing"
fi
echo
echo "Building signed package ..."
"${MONO}" "BuildTools/AutoUpdateBuilder/bin/Debug/AutoUpdateBuilder.exe" --input="${UPDATE_SOURCE}" \
--output="${UPDATE_TARGET}" --keyfile="${UPDATER_KEYFILE}" \
--manifest=Updates/${RELEASE_TYPE}.manifest --changeinfo="${RELEASE_CHANGEINFO}" \
--displayname="${RELEASE_NAME}" --remoteurls="${UPDATE_ZIP_URLS}" \
--version="${RELEASE_VERSION}" --keyfile-password="${KEYFILE_PASSWORD}"
if [ ! -f "${UPDATE_TARGET}/package.zip" ]; then
"${MONO}" "BuildTools/UpdateVersionStamp/bin/Release/UpdateVersionStamp.exe" --version="${RELEASE_VERSION}"
echo "Something went wrong while building the package, no output found"
exit 5
fi
"${MONO}" "BuildTools/GnupgSigningTool/bin/Debug/GnupgSigningTool.exe" \
--inputfile=\"${UPDATE_TARGET}/package.zip\" \
--signaturefile=\"${UPDATE_TARGET}/package.zip.sig\" \
--armor=false --gpgkeyfile="${GPG_KEYFILE}" --gpgpath="${GPG}" \
--keyfile-password="${KEYFILE_PASSWORD}"
"${MONO}" "BuildTools/GnupgSigningTool/bin/Debug/GnupgSigningTool.exe" \
--inputfile=\"${UPDATE_TARGET}/package.zip\" \
--signaturefile=\"${UPDATE_TARGET}/package.zip.sig.asc\" \
--armor=true --gpgkeyfile="${GPG_KEYFILE}" --gpgpath="${GPG}" \
--keyfile-password="${KEYFILE_PASSWORD}"
echo "${RELEASE_INC_VERSION}" > "Updates/build_version.txt"
mv "${UPDATE_TARGET}/package.zip" "${UPDATE_TARGET}/latest.zip"
mv "${UPDATE_TARGET}/autoupdate.manifest" "${UPDATE_TARGET}/latest.manifest"
mv "${UPDATE_TARGET}/package.zip.sig" "${UPDATE_TARGET}/latest.zip.sig"
mv "${UPDATE_TARGET}/package.zip.sig.asc" "${UPDATE_TARGET}/latest.zip.sig.asc"
cp "${UPDATE_TARGET}/latest.zip" "${UPDATE_TARGET}/${RELEASE_FILE_NAME}.zip"
cp "${UPDATE_TARGET}/latest.manifest" "${UPDATE_TARGET}/${RELEASE_FILE_NAME}.manifest"
cp "${UPDATE_TARGET}/latest.zip.sig" "${UPDATE_TARGET}/${RELEASE_FILE_NAME}.zip.sig"
cp "${UPDATE_TARGET}/latest.zip.sig.asc" "${UPDATE_TARGET}/${RELEASE_FILE_NAME}.zip.sig.asc"
"${MONO}" "BuildTools/UpdateVersionStamp/bin/Release/UpdateVersionStamp.exe" --version="${RELEASE_VERSION}"
echo "Uploading binaries"
"${AWS}" --profile=duplicati-upload s3 cp "${UPDATE_TARGET}/${RELEASE_FILE_NAME}.zip" "s3://${S3_BUCKET_NAME}/${RELEASE_TYPE}/${RELEASE_FILE_NAME}.zip"
"${AWS}" --profile=duplicati-upload s3 cp "${UPDATE_TARGET}/${RELEASE_FILE_NAME}.zip.sig" "s3://${S3_BUCKET_NAME}/${RELEASE_TYPE}/${RELEASE_FILE_NAME}.zip.sig"
"${AWS}" --profile=duplicati-upload s3 cp "${UPDATE_TARGET}/${RELEASE_FILE_NAME}.zip.sig.asc" "s3://${S3_BUCKET_NAME}/${RELEASE_TYPE}/${RELEASE_FILE_NAME}.zip.sig.asc"
"${AWS}" --profile=duplicati-upload s3 cp "${UPDATE_TARGET}/${RELEASE_FILE_NAME}.manifest" "s3://${S3_BUCKET_NAME}/${RELEASE_TYPE}/${RELEASE_FILE_NAME}.manifest"
"${AWS}" --profile=duplicati-upload s3 cp "s3://${S3_BUCKET_NAME}/${RELEASE_TYPE}/${RELEASE_FILE_NAME}.manifest" "s3://${S3_BUCKET_NAME}/${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}')
ZIP_SHA256=$(shasum -a 256 ${UPDATE_TARGET}/${RELEASE_FILE_NAME}.zip | awk -F ' ' '{print $1}')
cat > "latest.json" <<EOF
{
"version": "${RELEASE_VERSION}",
"zip": "${RELEASE_FILE_NAME}.zip",
"zipsig": "${RELEASE_FILE_NAME}.zip.sig",
"zipsigasc": "${RELEASE_FILE_NAME}.zip.sig.asc",
"manifest": "${RELEASE_FILE_NAME}.manifest",
"urlbase": "https://updates.duplicati.com/${RELEASE_TYPE}/",
"link": "https://updates.duplicati.com/${RELEASE_TYPE}/${RELEASE_FILE_NAME}.zip",
"zipmd5": "${ZIP_MD5}",
"zipsha1": "${ZIP_SHA1}",
"zipsha256": "${ZIP_SHA256}"
}
EOF
echo "duplicati_version_info =" > "latest.js"
cat "latest.json" >> "latest.js"
echo ";" >> "latest.js"
"${AWS}" --profile=duplicati-upload s3 cp "latest.json" "s3://${S3_BUCKET_NAME}/${RELEASE_TYPE}/latest.json"
"${AWS}" --profile=duplicati-upload s3 cp "latest.js" "s3://${S3_BUCKET_NAME}/${RELEASE_TYPE}/latest.js"
# echo "Propagating to other build types"
# for OTHER in ${OTHER_UPLOADS}; do
# aws --profile=duplicati-upload s3 cp "s3://${S3_BUCKET_NAME}/${RELEASE_TYPE}/${RELEASE_FILE_NAME}.manifest" "s3://${S3_BUCKET_NAME}/${OTHER}/latest.manifest"
# aws --profile=duplicati-upload s3 cp "s3://${S3_BUCKET_NAME}/${RELEASE_TYPE}/latest.json" "s3://${S3_BUCKET_NAME}/${OTHER}/latest.json"
# done
rm "${RELEASE_CHANGELOG_NEWS_FILE}"
git checkout "Duplicati/License/VersionTag.txt"
git checkout "Duplicati/Library/AutoUpdater/AutoUpdateURL.txt"
git checkout "Duplicati/Library/AutoUpdater/AutoUpdateBuildChannel.txt"
git add "Updates/build_version.txt"
git add "${RELEASE_CHANGELOG_FILE}"
git commit -m "Version bump to v${RELEASE_VERSION}-${RELEASE_NAME}" -m "You can download this build from: " -m "Binaries: https://updates.duplicati.com/${RELEASE_TYPE}/${RELEASE_FILE_NAME}.zip" -m "Signature file: https://updates.duplicati.com/${RELEASE_TYPE}/${RELEASE_FILE_NAME}.zip.sig" -m "ASCII signature file: https://updates.duplicati.com/${RELEASE_TYPE}/${RELEASE_FILE_NAME}.zip.sig.asc" -m "MD5: ${ZIP_MD5}" -m "SHA1: ${ZIP_SHA1}" -m "SHA256: ${ZIP_SHA256}"
git tag "v${RELEASE_VERSION}-${RELEASE_NAME}" -m "You can download this build from: " -m "Binaries: https://updates.duplicati.com/${RELEASE_TYPE}/${RELEASE_FILE_NAME}.zip" -m "Signature file: https://updates.duplicati.com/${RELEASE_TYPE}/${RELEASE_FILE_NAME}.zip.sig" -m "ASCII signature file: https://updates.duplicati.com/${RELEASE_TYPE}/${RELEASE_FILE_NAME}.zip.sig.asc" -m "MD5: ${ZIP_MD5}" -m "SHA1: ${ZIP_SHA1}" -m "SHA256: ${ZIP_SHA256}"
git push --tags
PRE_RELEASE_LABEL="--pre-release"
if [ "${RELEASE_TYPE}" == "stable" ]; then
PRE_RELEASE_LABEL=""
fi
RELEASE_MESSAGE=$(printf "Changes in this version:\n${RELEASE_CHANGEINFO_NEWS}")
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} \
--tag "v${RELEASE_VERSION}-${RELEASE_NAME}" \
--name "v${RELEASE_VERSION}-${RELEASE_NAME}" \
--repo "duplicati" \
--user "duplicati" \
--security-token "${GITHUB_TOKEN}" \
--description "${RELEASE_MESSAGE}" \
"${GITHUB_RELEASE}" upload \
--tag "v${RELEASE_VERSION}-${RELEASE_NAME}" \
--name "${RELEASE_FILE_NAME}.zip" \
--repo "duplicati" \
--user "duplicati" \
--security-token "${GITHUB_TOKEN}" \
--file "${UPDATE_TARGET}/${RELEASE_FILE_NAME}.zip"
fi
DISCOURSE_TOKEN=$(cat "${DISCOURSE_TOKEN_FILE}")
if [ "x${DISCOURSE_TOKEN}" == "x" ]; then
echo "No DISCOURSE_TOKEN found in environment, you can manually create the post on the forum"
else
body="# [${RELEASE_VERSION}-${RELEASE_NAME}](https://github.com/duplicati/duplicati/releases/tag/v${RELEASE_VERSION}-${RELEASE_NAME})
${RELEASE_CHANGEINFO_NEWS}
"
DISCOURSE_USERNAME=$(echo "${DISCOURSE_TOKEN}" | cut -d ":" -f 1)
DISCOURSE_APIKEY=$(echo "${DISCOURSE_TOKEN}" | cut -d ":" -f 2)
curl -X POST "https://forum.duplicati.com/posts" \
-H "Content-Type: multipart/form-data" \
-H "Accept: application/json" \
-H "Api-Key: ${DISCOURSE_APIKEY}" \
-H "Api-Username: ${DISCOURSE_USERNAME}" \
-F "category=10" \
-F "title=Release: ${RELEASE_VERSION} (${RELEASE_TYPE}) ${RELEASE_TIMESTAMP}" \
-F "raw=${body}"
fi
git push
echo
echo "Built ${RELEASE_TYPE} version: ${RELEASE_VERSION} - ${RELEASE_NAME}"
echo " in folder: ${UPDATE_TARGET}"
echo
echo
echo "Building installers ..."
# Send the password along to avoid typing it again
export KEYFILE_PASSWORD
bash "build-installers.sh" "${UPDATE_TARGET}/${RELEASE_FILE_NAME}.zip"
-25
View File
@@ -1,25 +0,0 @@
RELEASE_TIMESTAMP=`date +%Y-%m-%d`
RELEASE_INC_VERSION=`cat Updates/debug_version.txt`
RELEASE_INC_VERSION=$((RELEASE_INC_VERSION+0))
RELEASE_NAME=2.0_CLI_experimental_${RELEASE_TIMESTAMP}
RELEASE_CHANGEINFO=`cat Updates/debug_changeinfo.txt`
RELEASE_VERSION="2.0.0.${RELEASE_INC_VERSION}"
echo "${RELEASE_NAME}" > Duplicati/License/VersionTag.txt
cp "Updates/debug_urls.txt" Duplicati/Library/AutoUpdater/AutoUpdateURL.txt
cp "Updates/debug_key.txt" Duplicati/Library/AutoUpdater/AutoUpdateSignKeys.txt
mono BuildTools/UpdateVersionStamp/bin/Debug/UpdateVersionStamp.exe --version="${RELEASE_VERSION}"
xbuild /p:Configuration=Debug Duplicati.sln
rm Duplicati/GUI/Duplicati.GUI.TrayIcon/bin/Debug/*.mdb
rm -rf Duplicati/GUI/Duplicati.GUI.TrayIcon/bin/Debug/control_dir
rm Duplicati/GUI/Duplicati.GUI.TrayIcon/bin/Debug/Duplicati-server.sqlite
rm Duplicati/GUI/Duplicati.GUI.TrayIcon/bin/Debug/Duplicati.debug.log
rm -rf Duplicati/GUI/Duplicati.GUI.TrayIcon/bin/Debug/updates
cp -R Duplicati/GUI/Duplicati.GUI.TrayIcon/bin/Debug/* ~/Dropbox/Duplicati/2.0/2.0_snapshot/
cp -R Duplicati/Server/webroot ~/Dropbox/Duplicati/2.0/2.0_snapshot/
mono BuildTools/UpdateVersionStamp/bin/Debug/UpdateVersionStamp.exe --version="2.0.0.7"
-23
View File
@@ -1,23 +0,0 @@
#!/usr/bin/env python
from __future__ import print_function
import re
import io
with open('Duplicati.sln', 'r') as f:
c = f.read()
p = re.compile(r"\{[0-9a-fA-F\-]*\}")
tags = p.findall(c)
d = {}
for n in tags:
d[n] = 0
for n in tags:
d[n] = d[n] + 1
for n in d:
if d[n] > 7:
print(n)
-2
View File
@@ -1,2 +0,0 @@
cd Installer/Makefile
make $@
-7
View File
@@ -1,7 +0,0 @@
find Duplicati -type f -name *.html -exec sed -i '' $'s/\t/ /g' {} +
find Duplicati -type f -name *.js -exec sed -i '' $'s/\t/ /g' {} +
find Duplicati -type f -name *.css -exec sed -i '' $'s/\t/ /g' {} +
find Duplicati -type f -name *.cs -exec sed -i '' $'s/\t/ /g' {} +
find Duplicati -type f -name *.txt -exec sed -i '' $'s/\t/ /g' {} +
find Duplicati -type f -name *.cs | xargs python unix2dos.py
-14
View File
@@ -1,14 +0,0 @@
#!/usr/bin/env python
import sys
for fname in sys.argv[1:]:
with open(fname, 'rb') as infile:
instr = infile.read()
outstr = instr.replace( b"\r\n", b"\n" ).replace( b"\r", b"\n" ).replace( b"\n", b"\r\n" )
if len(outstr) == len(instr):
continue
with open( fname, "wb" ) as outfile:
outfile.write( outstr )