Removed unused files.
Moved installer files into the ReleaseBuilder
@@ -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
|
||||
@@ -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/**/*
|
||||
|
||||
@@ -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/**/*
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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()}",
|
||||
"."
|
||||
]);
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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" ?>
|
||||
|
||||
|
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 |
@@ -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}"
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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"
|
||||
|
||||
|
||||
@@ -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"
|
||||
@@ -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)
|
||||
@@ -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
|
||||
@@ -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 )
|
||||