# This makefile automates the release build process.
# RELEASENUM and RELEASENAME are derived from the contents of version.mfc.
# The RELEASEDIR should be set to whatever works for you.
#
# 'make' or 'make release'
# will build both binary and source zipfiles.
# bin-release or src-release will build only what their names imply.
#
# Oh, this works with GNU make under Cygwin. YMMV on other makes...

RELEASEDIR := /cygdrive/c/local/src/PasswordSafe/Releases

# Shouldn't need to change anything below this line

include version.mfc
ifeq ($(VER_REV),)
	RELEASENUM := $(VER_MAJOR).$(VER_MINOR)
else
	RELEASENUM := $(VER_MAJOR).$(VER_MINOR).$(VER_REV)
endif
RELEASE_SPECIAL := $(VER_SPECIAL)

RELEASENAME= $(RELEASENUM)$(RELEASE_SPECIAL)
BINRELNAME := pwsafe-$(RELEASENAME)-bin
BINRELNAME64 := pwsafe64-$(RELEASENAME)-bin
SRCRELNAME := pwsafe-$(RELEASENAME)-src

RM := /usr/bin/rm
CP := /usr/bin/cp
MV := /usr/bin/mv
MKDIR := /usr/bin/mkdir -p
TAR := /usr/bin/tar
SED := /usr/bin/sed
ZIP := /usr/bin/zip
GIT := /usr/bin/git
GPG := /usr/bin/gpg
GPG_SIGN := $(GPG) --detach-sign --default-key $(GPG_KEY)
SHA1SUM := /usr/bin/sha1sum
SF_UPLOAD_CMD := /usr/bin/rsync -avP -e ssh
SF_UPLOAD_DST :=  $(SF_UPLOAD_ROOT)/passwordsafe/Windows/$(RELEASENUM)
# GitHub upload utility from https://github.com/aktau/github-release
GH_UPLOAD_CMD := /usr/local/bin/github-release
export GITHUB_USER := pwsafe
export GITHUB_REPO := pwsafe
PYTHON := /usr/bin/python
MAKENSIS := /cygdrive/c/local/NSIS/makensis.exe
WIXDIR := /cygdrive/c/local/WIX
CANDLE := $(WIXDIR)/candle.exe
LIGHT := $(WIXDIR)/light.exe
SIGNTOOL := /cygdrive/c/Program\ Files\ \(x86\)/Windows\ Kits/10/bin/10.0.19041.0/x64/signtool.exe
SIGNTOOL_ARGS := /t http://timestamp.digicert.com /a /fd sha256 

RELTAG = V$(subst .,_,$(RELEASENAME))

I18N_DIR := ./src/ui/Windows/I18N
I18N_DLL_DIR := ./out/build/x86-Release/I18N
I18N_DLL_DIR_64 := ./out/build/x64-Release/I18N
POT_FILE := $(I18N_DIR)/pwsafe.pot
HELP_DIR := ./help
BIN_DIR := ./out/build/x86-Release/Release/
BIN_DIR_64 := ./out/build/x64-Release/Release/
TMPDIR := /tmp
RELNOTES := $(CURDIR)/docs/ReleaseNotes.md

XMLS := $(foreach i,\
				  pwsafe.xsd pwsafe_filter.xsd pwsafe.xsl \
					KPV1_to_PWS.xslt KPV2_to_PWS.xslt,\
				  xml/$i)
I18N_HELPS := $(foreach i,\
								DE ES FR RU ZH,\
								help/pwsafe$(i)/pwsafe$(i).chm)
I18N_DLLS := $(foreach i,\
								AR CZ DE ES PL RU SV ZH FR DK KR NL,\
								$(I18N_DLL_DIR)/pwsafe$(i).dll)
I18N_DLLS_64 := $(foreach i,\
								AR CZ DE ES PL RU SV ZH FR DK KR NL,\
								$(I18N_DLL_DIR_64)/pwsafe$(i).dll)

BIN_MANIFEST = README.md docs/ReleaseNotes.md LICENSE \
    $(XMLS) \
		docs/ChangeLog.txt $(BIN_DIR)/pwsafe.exe $(BIN_DIR)/pwsafe-cli.exe $(BIN_DIR)/pws_at.dll \
		$(BIN_DIR)/pws_osk.dll help/default/pwsafe.chm \
		docs/pad_file.xml
BIN_MANIFEST_64 = README.md docs/ReleaseNotes.md LICENSE \
    $(XMLS) \
		docs/ChangeLog.txt $(BIN_DIR_64)/pwsafe.exe $(BIN_DIR_64)/pwsafe-cli.exe $(BIN_DIR_64)/pws_at.dll \
		$(BIN_DIR_64)/pws_osk.dll help/default/pwsafe.chm \
		docs/pad_file.xml

I18N_MANIFEST := $(I18N_HELPS) $(I18N_DLLS)
I18N_MANIFEST_64 := $(I18N_HELPS) $(I18N_DLLS_64)

# MSVSVER is the version of Visual Studio
# Currently supported values are
# * 11 for Visual Studio 2012
# * 12 for Visual Studio 2013
# * 14 for Visual Studio 2015
# * 16 for Visual Studio 2019 (Community Edition)
# This can be set by a higher-level Makefile

MSVSVER ?= 16

ifeq ($(MSVSVER),11)
VCBUILD = /cygdrive/c/WINDOWS/Microsoft.NET/Framework/v4.0.30319/MSBuild.exe
else ifeq ($(MSVSVER),12)
VCBUILD = "/cygdrive/c/Program Files (x86)/MSBuild/12.0/Bin/MSBuild.exe"
else ifeq ($(MSVSVER),14)
VCBUILD = "/cygdrive/c/Program Files (x86)/MSBuild/14.0/Bin/MSBuild.exe"
else ifeq ($(MSVSVER),16)
VCBUILD = "/cygdrive/c/Program Files (x86)/Microsoft Visual Studio/2019/Community/MSBuild/Current/Bin"
else
$(error "Unsupported MSVSVER")
endif

.PHONY: all release bin-release bin-release-64 src-release installables signatures \
	upload upload-sf upload-github upload-latest sha1sums msi msi-64 nsis nsis-64 \
	update-pos i18n save-map save-map-64 help git-tag build cmpsrc-github

all: help release installables signatures sha1sums

upload: upload-sf upload-github upload-latest

upload-sf:
	(cd $(RELEASEDIR); \
	 $(SF_UPLOAD_CMD) pwsafe-$(RELEASENAME).exe \
	 $(BINRELNAME).zip $(SRCRELNAME).zip \
	 pwsafe-$(RELEASENAME).msi \
	 pwsafe-$(RELEASENAME)-map+pdb.zip \
	$(RELNOTES) \
	 pwsafe-$(RELEASENAME).msi.sig \
	 pwsafe-$(RELEASENAME).exe.sig \
	 $(BINRELNAME).zip.sig $(SRCRELNAME).zip.sig \
	 pwsafe64-$(RELEASENAME).exe \
	 pwsafe64-$(RELEASENAME).msi \
	 pwsafe64-$(RELEASENAME)-map+pdb.zip \
	 $(BINRELNAME64).zip $(BINRELNAME64).zip.sig \
	 pwsafe64-$(RELEASENAME).msi.sig \
	 pwsafe64-$(RELEASENAME).exe.sig \
	 $(SF_UPLOAD_DST))

upload-github:
ifeq ($(GITHUB_TOKEN),)
	$(error "GITHUB_TOKEN not set")
endif
	-$(GH_UPLOAD_CMD) release -t $(RELEASENAME) -d "PasswordSafe release $(RELEASENAME)"
	(cd $(RELEASEDIR); \
		$(GH_UPLOAD_CMD) upload -t $(RELEASENAME) -n pwsafe-$(RELEASENAME).exe -f pwsafe-$(RELEASENAME).exe; \
		$(GH_UPLOAD_CMD) upload -t $(RELEASENAME) -n pwsafe-$(RELEASENAME).exe.sig -f pwsafe-$(RELEASENAME).exe.sig; \
		$(GH_UPLOAD_CMD) upload -t $(RELEASENAME) -n pwsafe-$(RELEASENAME).msi -f pwsafe-$(RELEASENAME).msi; \
		$(GH_UPLOAD_CMD) upload -t $(RELEASENAME) -n pwsafe-$(RELEASENAME).msi.sig -f pwsafe-$(RELEASENAME).msi.sig; \
		$(GH_UPLOAD_CMD) upload -t $(RELEASENAME) -n pwsafe64-$(RELEASENAME).exe -f pwsafe64-$(RELEASENAME).exe; \
		$(GH_UPLOAD_CMD) upload -t $(RELEASENAME) -n pwsafe64-$(RELEASENAME).exe.sig -f pwsafe64-$(RELEASENAME).exe.sig; \
		$(GH_UPLOAD_CMD) upload -t $(RELEASENAME) -n pwsafe64-$(RELEASENAME).msi -f pwsafe64-$(RELEASENAME).msi; \
		$(GH_UPLOAD_CMD) upload -t $(RELEASENAME) -n pwsafe64-$(RELEASENAME).msi.sig -f pwsafe64-$(RELEASENAME).msi.sig; \
		$(GH_UPLOAD_CMD) upload -t $(RELEASENAME) -n $(BINRELNAME).zip -f $(BINRELNAME).zip; \
		$(GH_UPLOAD_CMD) upload -t $(RELEASENAME) -n $(BINRELNAME).zip.sig -f $(BINRELNAME).zip.sig; \
		$(GH_UPLOAD_CMD) upload -t $(RELEASENAME) -n $(BINRELNAME64).zip -f $(BINRELNAME64).zip; \
		$(GH_UPLOAD_CMD) upload -t $(RELEASENAME) -n $(BINRELNAME64).zip.sig -f $(BINRELNAME64).zip.sig; \
		$(GH_UPLOAD_CMD) upload -t $(RELEASENAME) -n pwsafe-$(RELEASENAME)-map+pdb.zip \
			-f pwsafe-$(RELEASENAME)-map+pdb.zip; \
		$(GH_UPLOAD_CMD) upload -t $(RELEASENAME) -n pwsafe64-$(RELEASENAME)-map+pdb.zip \
			-f pwsafe64-$(RELEASENAME)-map+pdb.zip)
	(cd docs; $(GH_UPLOAD_CMD) upload -t $(RELEASENAME) -n ReleaseNotes.md -f ReleaseNotes.md)

# Following needed because GitHub creates its own tar.gz and .zip files for a release
# and we need to verify those before signing them
cmpsrc-github:
	(cd $(TMPDIR); unzip -q $(RELEASEDIR)/$(SRCRELNAME).zip)
	./Misc/sighlp_cmp.py -f ChangeLog -f pwsafe.pot -f version.h -v 0 -s $(TMPDIR)/$(RELEASENAME).zip \
												https://github.com/pwsafe/$(GITHUB_REPO)/archive/$(RELEASENAME).zip \
												$(TMPDIR)/pwsafe-$(RELEASENAME)-src/ && $(GPG_SIGN) $(TMPDIR)/$(RELEASENAME).zip \
												&& $(RM) $(TMPDIR)/$(RELEASENAME).zip
	./Misc/sighlp_cmp.py -f ChangeLog -f pwsafe.pot -f version.h -v 0 -s $(TMPDIR)/$(RELEASENAME).tar.gz \
												https://github.com/pwsafe/$(GITHUB_REPO)/archive/$(RELEASENAME).tar.gz \
												$(TMPDIR)/pwsafe-$(RELEASENAME)-src/ && $(GPG_SIGN) $(TMPDIR)/$(RELEASENAME).tar.gz \
												&& $(RM) $(TMPDIR)/$(RELEASENAME).tar.gz
	@$(RM) -rf $(TMPDIR)/pwsafe-$(RELEASENAME)-src/
	@echo "GitHub source signature files ready to upload from $(TMPDIR)"

upload-latest: latest.xml
	echo "cd public_html" > putlatest.tmp
	echo "put $<" >> putlatest.tmp
	echo "cd padfiles" >> putlatest.tmp
	echo "put docs/pad_file.xml pwsafe.xml"
	sftp -b putlatest.tmp pwsafe.org
	$(RM) putlatest.tmp latest.xml

latest.xml: version.mfc version.wx
	Misc/make-latest-xml.pl $^ > $@
	@chmod 644 $@

sha1sums:
	(cd $(RELEASEDIR); \
	 $(SHA1SUM) pwsafe-$(RELEASENAME).exe \
	 pwsafe-$(RELEASENAME).msi \
	 pwsafe64-$(RELEASENAME).exe \
	 pwsafe64-$(RELEASENAME).msi \
	 $(BINRELNAME).zip \
	 $(BINRELNAME64).zip \
	 $(SRCRELNAME).zip)

signatures:
	$(GPG_SIGN) $(RELEASEDIR)/pwsafe-$(RELEASENAME).exe
	$(GPG_SIGN) $(RELEASEDIR)/pwsafe64-$(RELEASENAME).exe
	$(GPG_SIGN) $(RELEASEDIR)/$(BINRELNAME).zip
	$(GPG_SIGN) $(RELEASEDIR)/$(BINRELNAME64).zip
	$(GPG_SIGN) $(RELEASEDIR)/$(SRCRELNAME).zip
	$(GPG_SIGN) $(RELEASEDIR)/pwsafe-$(RELEASENAME).msi
	$(GPG_SIGN) $(RELEASEDIR)/pwsafe64-$(RELEASENAME).msi

installables: nsis msi nsis-64 msi-64

nsis:
	$(MAKENSIS) /DVERSION=$(RELEASENUM) /DARCH=x86 /DVER_SPECIAL=$(VER_SPECIAL) install/windows/pwsafe.nsi
	(cd install/windows; $(SIGNTOOL) sign $(SIGNTOOL_ARGS) pwsafe-$(RELEASENAME).exe)
	$(MV) install/windows/pwsafe-$(RELEASENAME).exe $(RELEASEDIR)

nsis-64:
	$(MAKENSIS) /DVERSION=$(RELEASENUM) /DARCH=x64 /DVER_SPECIAL=$(VER_SPECIAL) install/windows/pwsafe.nsi
	(cd install/windows; $(SIGNTOOL) sign $(SIGNTOOL_ARGS) pwsafe64-$(RELEASENAME).exe)
	$(MV) install/windows/pwsafe64-$(RELEASENAME).exe $(RELEASEDIR)

msi:
	$(CANDLE) -dPWSAFE_VERSION=$(RELEASENUM) -dPlatform=x86 install/windows/pwsafe.wxs
	$(LIGHT) -ext WixUIExtension -cultures:en-us pwsafe.wixobj \
					-out pwsafe.msi
	$(SIGNTOOL) sign $(SIGNTOOL_ARGS) pwsafe.msi
	$(MV) pwsafe.msi $(RELEASEDIR)/pwsafe-$(RELEASENAME).msi
	$(RM) pwsafe.wixobj

msi-64:
	$(CANDLE) -dPWSAFE_VERSION=$(RELEASENUM) -dPlatform=x64 -arch x64 install/windows/pwsafe.wxs
	$(LIGHT) -ext WixUIExtension -cultures:en-us pwsafe.wixobj \
					-out pwsafe64.msi
	$(SIGNTOOL) sign $(SIGNTOOL_ARGS) pwsafe64.msi
	$(MV) pwsafe64.msi $(RELEASEDIR)/pwsafe64-$(RELEASENAME).msi
	$(RM) pwsafe.wixobj

release:  i18n bin-release bin-release-64 src-release

bin-release: sign-bins save-map
	@-mkdir $(RELEASEDIR)/$(BINRELNAME)
	$(CP) $(BIN_MANIFEST) $(RELEASEDIR)/$(BINRELNAME)
	$(CP) $(I18N_MANIFEST) $(RELEASEDIR)/$(BINRELNAME)
	(cd $(RELEASEDIR); $(ZIP) -9 -r  foo ./$(BINRELNAME); \
	$(MV) foo.zip $(BINRELNAME).zip)
	@$(RM) -rf $(RELEASEDIR)/$(BINRELNAME)

sign-bins:
	$(SIGNTOOL) sign $(SIGNTOOL_ARGS) $(BIN_DIR)/pwsafe.exe $(BIN_DIR)/pwsafe-cli.exe \
	$(BIN_DIR)/pws_at.dll $(BIN_DIR)/pws_osk.dll $(I18N_DLLS)

save-map:
	$(ZIP) -9 $(RELEASEDIR)/pwsafe-$(RELEASENAME)-map+pdb.zip \
	 $(BIN_DIR)/pwsafe.map $(BIN_DIR)/pwsafe.pdb \
   $(BIN_DIR)/pws_*.pdb		

bin-release-64: sign-bins-64 save-map-64
	@-mkdir $(RELEASEDIR)/$(BINRELNAME64)
	$(CP) $(BIN_MANIFEST_64) $(RELEASEDIR)/$(BINRELNAME64)
	$(CP) $(I18N_MANIFEST_64) $(RELEASEDIR)/$(BINRELNAME64)
	(cd $(RELEASEDIR); $(ZIP) -9 -r  foo ./$(BINRELNAME64); \
	$(MV) foo.zip $(BINRELNAME64).zip)
	@$(RM) -rf $(RELEASEDIR)/$(BINRELNAME64)

sign-bins-64:
	$(SIGNTOOL) sign $(SIGNTOOL_ARGS) $(BIN_DIR_64)/pwsafe.exe $(BIN_DIR_64)/pwsafe-cli.exe \
	$(BIN_DIR_64)/pws_at.dll $(BIN_DIR_64)/pws_osk.dll $(I18N_DLLS_64)

save-map-64:
	$(ZIP) -9 $(RELEASEDIR)/pwsafe64-$(RELEASENAME)-map+pdb.zip \
	 $(BIN_DIR_64)/pwsafe.map $(BIN_DIR_64)/pwsafe.pdb \
   $(BIN_DIR_64)/pws_*.pdb		

src-release: ChangeLog $(POT_FILE)
	@$(MKDIR) $(RELEASEDIR)/$(SRCRELNAME)
	$(GIT) archive HEAD | $(TAR) -x -C $(RELEASEDIR)/$(SRCRELNAME)
	$(MV) ChangeLog $(RELEASEDIR)/$(SRCRELNAME)
	$(CP) out/build/x64-Release/version.h $(RELEASEDIR)/$(SRCRELNAME)/src/ui/Windows
	$(CP) $(POT_FILE) $(RELEASEDIR)/$(SRCRELNAME)
	(cd $(RELEASEDIR); $(ZIP) -9 -r  bar ./$(SRCRELNAME); \
	$(MV) bar.zip $(SRCRELNAME).zip)
	@$(RM) -rf $(RELEASEDIR)/$(SRCRELNAME)

# Builds 32 and 64 bit versions of pwsafe
build:
	$(VCBUILD) /t:rebuild /p:Configuration=Release /p:Platform=x86 pwsafe-$(MSVSVER).sln
	$(VCBUILD) /t:rebuild /p:Configuration=Release /p:Platform=x64 pwsafe-$(MSVSVER).sln

ChangeLog:
	$(GIT) --no-pager log --format="%ai %aN %n%n%x09* %s%d%n" > $@

$(POT_FILE): $(BIN_DIR)/../release/pwsafe_base.dll
	$(MAKE) -C $(I18N_DIR) pwsafe.pot

update-pos:
	$(MAKE) -C $(I18N_DIR) $@

i18n:
	$(MAKE) -C $(I18N_DIR) dlls

help:
	$(MAKE) -C $(HELP_DIR)

git-tag:
	$(GIT) tag -u $(GPG_KEY) -m "tag $(RELEASENAME) release" $(RELEASENAME)

# Local variables:
# mode: Makefile
# End:
