зеркало из https://github.com/microsoft/git.git
Merge pull request #399 from vdye/feature/build-installers
Implement workflow to create GitHub release with attached `git` installers
This commit is contained in:
Коммит
321b77c6d8
|
@ -0,0 +1,116 @@
|
||||||
|
SHELL := /bin/bash
|
||||||
|
SUDO := sudo
|
||||||
|
C_INCLUDE_PATH := /usr/include
|
||||||
|
CPLUS_INCLUDE_PATH := /usr/include
|
||||||
|
LD_LIBRARY_PATH := /usr/lib
|
||||||
|
|
||||||
|
OSX_VERSION := $(shell sw_vers -productVersion)
|
||||||
|
TARGET_FLAGS := -mmacosx-version-min=$(OSX_VERSION) -DMACOSX_DEPLOYMENT_TARGET=$(OSX_VERSION)
|
||||||
|
|
||||||
|
ARCH := x86_64
|
||||||
|
ARCH_CODE := x86_64
|
||||||
|
ARCH_FLAGS_x86_64 := -arch x86_64
|
||||||
|
|
||||||
|
CFLAGS := $(TARGET_FLAGS) $(ARCH_FLAGS_${ARCH_CODE})
|
||||||
|
LDFLAGS := $(TARGET_FLAGS) $(ARCH_FLAGS_${ARCH_CODE})
|
||||||
|
|
||||||
|
PREFIX := /usr/local
|
||||||
|
GIT_PREFIX := $(PREFIX)/git
|
||||||
|
|
||||||
|
BUILD_CODE := intel-$(ARCH_CODE)
|
||||||
|
BUILD_DIR := $(GITHUB_WORKSPACE)/payload
|
||||||
|
DESTDIR := $(PWD)/stage/git-$(BUILD_CODE)-$(VERSION)
|
||||||
|
ARTIFACTDIR := build_artifacts
|
||||||
|
SUBMAKE := $(MAKE) C_INCLUDE_PATH="$(C_INCLUDE_PATH)" CPLUS_INCLUDE_PATH="$(CPLUS_INCLUDE_PATH)" LD_LIBRARY_PATH="$(LD_LIBRARY_PATH)" TARGET_FLAGS="$(TARGET_FLAGS)" CFLAGS="$(CFLAGS)" LDFLAGS="$(LDFLAGS)" NO_GETTEXT=1 NO_DARWIN_PORTS=1 prefix=$(GIT_PREFIX) DESTDIR=$(DESTDIR)
|
||||||
|
CORES := $(shell bash -c "sysctl hw.ncpu | awk '{print \$$2}'")
|
||||||
|
|
||||||
|
.PHONY: image pkg payload
|
||||||
|
|
||||||
|
.SECONDARY:
|
||||||
|
|
||||||
|
$(DESTDIR)$(GIT_PREFIX)/VERSION-$(VERSION)-$(BUILD_CODE):
|
||||||
|
rm -f $(BUILD_DIR)/git-$(VERSION)/osx-installed*
|
||||||
|
mkdir -p $(DESTDIR)$(GIT_PREFIX)
|
||||||
|
touch $@
|
||||||
|
|
||||||
|
$(BUILD_DIR)/git-$(VERSION)/osx-built-keychain:
|
||||||
|
cd $(BUILD_DIR)/git-$(VERSION)/contrib/credential/osxkeychain; $(SUBMAKE) CFLAGS="$(CFLAGS) -g -O2 -Wall"
|
||||||
|
touch $@
|
||||||
|
|
||||||
|
$(BUILD_DIR)/git-$(VERSION)/osx-built:
|
||||||
|
[ -d $(DESTDIR)$(GIT_PREFIX) ] && $(SUDO) rm -rf $(DESTDIR) || echo ok
|
||||||
|
cd $(BUILD_DIR)/git-$(VERSION); $(SUBMAKE) -j $(CORES) all strip
|
||||||
|
touch $@
|
||||||
|
|
||||||
|
$(BUILD_DIR)/git-$(VERSION)/osx-installed-bin: $(BUILD_DIR)/git-$(VERSION)/osx-built $(BUILD_DIR)/git-$(VERSION)/osx-built-keychain
|
||||||
|
cd $(BUILD_DIR)/git-$(VERSION); $(SUBMAKE) install
|
||||||
|
cp $(BUILD_DIR)/git-$(VERSION)/contrib/credential/osxkeychain/git-credential-osxkeychain $(DESTDIR)$(GIT_PREFIX)/bin/git-credential-osxkeychain
|
||||||
|
mkdir -p $(DESTDIR)$(GIT_PREFIX)/contrib/completion
|
||||||
|
cp $(BUILD_DIR)/git-$(VERSION)/contrib/completion/git-completion.bash $(DESTDIR)$(GIT_PREFIX)/contrib/completion/
|
||||||
|
cp $(BUILD_DIR)/git-$(VERSION)/contrib/completion/git-completion.zsh $(DESTDIR)$(GIT_PREFIX)/contrib/completion/
|
||||||
|
cp $(BUILD_DIR)/git-$(VERSION)/contrib/completion/git-prompt.sh $(DESTDIR)$(GIT_PREFIX)/contrib/completion/
|
||||||
|
# This is needed for Git-Gui, GitK
|
||||||
|
mkdir -p $(DESTDIR)$(GIT_PREFIX)/lib/perl5/site_perl
|
||||||
|
[ ! -f $(DESTDIR)$(GIT_PREFIX)/lib/perl5/site_perl/Error.pm ] && cp $(BUILD_DIR)/git-$(VERSION)/perl/private-Error.pm $(DESTDIR)$(GIT_PREFIX)/lib/perl5/site_perl/Error.pm || echo done
|
||||||
|
touch $@
|
||||||
|
|
||||||
|
$(BUILD_DIR)/git-$(VERSION)/osx-installed-man: $(BUILD_DIR)/git-$(VERSION)/osx-installed-bin
|
||||||
|
mkdir -p $(DESTDIR)$(GIT_PREFIX)/share/man
|
||||||
|
cp -R $(GITHUB_WORKSPACE)/manpages/ $(DESTDIR)$(GIT_PREFIX)/share/man
|
||||||
|
touch $@
|
||||||
|
|
||||||
|
$(BUILD_DIR)/git-$(VERSION)/osx-built-subtree:
|
||||||
|
cd $(BUILD_DIR)/git-$(VERSION)/contrib/subtree; $(SUBMAKE) XML_CATALOG_FILES="$(XML_CATALOG_FILES)" all git-subtree.1
|
||||||
|
touch $@
|
||||||
|
|
||||||
|
$(BUILD_DIR)/git-$(VERSION)/osx-installed-subtree: $(BUILD_DIR)/git-$(VERSION)/osx-built-subtree
|
||||||
|
mkdir -p $(DESTDIR)
|
||||||
|
cd $(BUILD_DIR)/git-$(VERSION)/contrib/subtree; $(SUBMAKE) XML_CATALOG_FILES="$(XML_CATALOG_FILES)" install install-man
|
||||||
|
touch $@
|
||||||
|
|
||||||
|
$(BUILD_DIR)/git-$(VERSION)/osx-installed-assets: $(BUILD_DIR)/git-$(VERSION)/osx-installed-bin
|
||||||
|
mkdir -p $(DESTDIR)$(GIT_PREFIX)/etc
|
||||||
|
cat assets/etc/gitconfig.osxkeychain >> $(DESTDIR)$(GIT_PREFIX)/etc/gitconfig
|
||||||
|
cp assets/uninstall.sh $(DESTDIR)$(GIT_PREFIX)/uninstall.sh
|
||||||
|
sh -c "echo .DS_Store >> $(DESTDIR)$(GIT_PREFIX)/share/git-core/templates/info/exclude"
|
||||||
|
|
||||||
|
symlinks:
|
||||||
|
mkdir -p $(ARTIFACTDIR)$(PREFIX)/bin
|
||||||
|
cd $(ARTIFACTDIR)$(PREFIX)/bin; find ../git/bin -type f -exec ln -sf {} \;
|
||||||
|
for man in man1 man3 man5 man7; do mkdir -p $(ARTIFACTDIR)$(PREFIX)/share/man/$$man; (cd $(ARTIFACTDIR)$(PREFIX)/share/man/$$man; ln -sf ../../../git/share/man/$$man/* ./); done
|
||||||
|
ruby ../scripts/symlink-git-hardlinks.rb $(ARTIFACTDIR)
|
||||||
|
touch $@
|
||||||
|
|
||||||
|
$(BUILD_DIR)/git-$(VERSION)/osx-installed: $(DESTDIR)$(GIT_PREFIX)/VERSION-$(VERSION)-$(BUILD_CODE) $(BUILD_DIR)/git-$(VERSION)/osx-installed-man $(BUILD_DIR)/git-$(VERSION)/osx-installed-assets $(BUILD_DIR)/git-$(VERSION)/osx-installed-subtree
|
||||||
|
find $(DESTDIR)$(GIT_PREFIX) -type d -exec chmod ugo+rx {} \;
|
||||||
|
find $(DESTDIR)$(GIT_PREFIX) -type f -exec chmod ugo+r {} \;
|
||||||
|
touch $@
|
||||||
|
|
||||||
|
$(BUILD_DIR)/git-$(VERSION)/osx-built-assert-$(ARCH_CODE): $(BUILD_DIR)/git-$(VERSION)/osx-built
|
||||||
|
ifeq ("$(ARCH_CODE)", "universal")
|
||||||
|
File $(BUILD_DIR)/git-$(VERSION)/git
|
||||||
|
File $(BUILD_DIR)/git-$(VERSION)/contrib/credential/osxkeychain/git-credential-osxkeychain
|
||||||
|
else
|
||||||
|
[ "$$(File $(BUILD_DIR)/git-$(VERSION)/git | cut -f 5 -d' ')" == "$(ARCH_CODE)" ]
|
||||||
|
[ "$$(File $(BUILD_DIR)/git-$(VERSION)/contrib/credential/osxkeychain/git-credential-osxkeychain | cut -f 5 -d' ')" == "$(ARCH_CODE)" ]
|
||||||
|
endif
|
||||||
|
touch $@
|
||||||
|
|
||||||
|
disk-image/VERSION-$(VERSION)-$(ARCH_CODE):
|
||||||
|
rm -f disk-image/*.pkg disk-image/VERSION-* disk-image/.DS_Store
|
||||||
|
mkdir disk-image
|
||||||
|
touch "$@"
|
||||||
|
|
||||||
|
disk-image/git-$(VERSION)-$(BUILD_CODE).pkg: disk-image/VERSION-$(VERSION)-$(ARCH_CODE) symlinks
|
||||||
|
pkgbuild --identifier com.git.pkg --version $(VERSION) --root $(ARTIFACTDIR)$(PREFIX) --scripts assets/scripts --install-location $(PREFIX) --component-plist ./assets/git-components.plist disk-image/git-$(VERSION)-$(BUILD_CODE).pkg
|
||||||
|
|
||||||
|
git-%-$(BUILD_CODE).dmg:
|
||||||
|
hdiutil create git-$(VERSION)-$(BUILD_CODE).uncompressed.dmg -fs HFS+ -srcfolder disk-image -volname "Git $(VERSION) Intel $(ARCH)" -ov
|
||||||
|
hdiutil convert -format UDZO -o $@ git-$(VERSION)-$(BUILD_CODE).uncompressed.dmg
|
||||||
|
rm -f git-$(VERSION)-$(BUILD_CODE).uncompressed.dmg
|
||||||
|
|
||||||
|
payload: $(BUILD_DIR)/git-$(VERSION)/osx-installed $(BUILD_DIR)/git-$(VERSION)/osx-built-assert-$(ARCH_CODE)
|
||||||
|
|
||||||
|
pkg: disk-image/git-$(VERSION)-$(BUILD_CODE).pkg
|
||||||
|
|
||||||
|
image: git-$(VERSION)-$(BUILD_CODE).dmg
|
|
@ -0,0 +1,2 @@
|
||||||
|
[credential]
|
||||||
|
helper = osxkeychain
|
|
@ -0,0 +1,18 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||||
|
<plist version="1.0">
|
||||||
|
<array>
|
||||||
|
<dict>
|
||||||
|
<key>BundleHasStrictIdentifier</key>
|
||||||
|
<true/>
|
||||||
|
<key>BundleIsRelocatable</key>
|
||||||
|
<false/>
|
||||||
|
<key>BundleIsVersionChecked</key>
|
||||||
|
<true/>
|
||||||
|
<key>BundleOverwriteAction</key>
|
||||||
|
<string>upgrade</string>
|
||||||
|
<key>RootRelativeBundlePath</key>
|
||||||
|
<string>git/share/git-gui/lib/Git Gui.app</string>
|
||||||
|
</dict>
|
||||||
|
</array>
|
||||||
|
</plist>
|
|
@ -0,0 +1,62 @@
|
||||||
|
#!/bin/bash
|
||||||
|
INSTALL_DST="$2"
|
||||||
|
SCALAR_C_CMD="$INSTALL_DST/git/bin/scalar"
|
||||||
|
SCALAR_DOTNET_CMD="/usr/local/scalar/scalar"
|
||||||
|
SCALAR_UNINSTALL_SCRIPT="/usr/local/scalar/uninstall_scalar.sh"
|
||||||
|
|
||||||
|
function cleanupScalar()
|
||||||
|
{
|
||||||
|
echo "checking whether Scalar was installed"
|
||||||
|
if [ ! -f "$SCALAR_C_CMD" ]; then
|
||||||
|
echo "Scalar not installed; exiting..."
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
echo "Scalar is installed!"
|
||||||
|
|
||||||
|
echo "looking for Scalar.NET"
|
||||||
|
if [ ! -f "$SCALAR_DOTNET_CMD" ]; then
|
||||||
|
echo "Scalar.NET not found; exiting..."
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
echo "Scalar.NET found!"
|
||||||
|
|
||||||
|
currentUser=$(echo "show State:/Users/ConsoleUser" | scutil | awk '/Name :/ { print $3 }')
|
||||||
|
|
||||||
|
# Re-register Scalar.NET repositories with the newly-installed Scalar
|
||||||
|
for repo in $($SCALAR_DOTNET_CMD list); do
|
||||||
|
(
|
||||||
|
PATH="$INSTALL_DST/git/bin:$PATH"
|
||||||
|
sudo -u "$currentUser" scalar register $repo || \
|
||||||
|
echo "warning: skipping re-registration of $repo"
|
||||||
|
)
|
||||||
|
done
|
||||||
|
|
||||||
|
# Uninstall Scalar.NET
|
||||||
|
echo "removing Scalar.NET"
|
||||||
|
|
||||||
|
# Add /usr/local/bin to path - default install location of Homebrew
|
||||||
|
PATH="/usr/local/bin:$PATH"
|
||||||
|
if (sudo -u "$currentUser" brew list --cask scalar); then
|
||||||
|
# Remove from Homebrew
|
||||||
|
sudo -u "$currentUser" brew remove --cask scalar || echo "warning: Scalar.NET uninstall via Homebrew completed with code $?"
|
||||||
|
echo "Scalar.NET uninstalled via Homebrew!"
|
||||||
|
elif (sudo -u "$currentUser" brew list --cask scalar-azrepos); then
|
||||||
|
sudo -u "$currentUser" brew remove --cask scalar-azrepos || echo "warning: Scalar.NET with GVFS uninstall via Homebrew completed with code $?"
|
||||||
|
echo "Scalar.NET with GVFS uninstalled via Homebrew!"
|
||||||
|
elif [ -f $SCALAR_UNINSTALL_SCRIPT ]; then
|
||||||
|
# If not installed with Homebrew, manually remove package
|
||||||
|
sudo -S sh $SCALAR_UNINSTALL_SCRIPT || echo "warning: Scalar.NET uninstall completed with code $?"
|
||||||
|
echo "Scalar.NET uninstalled!"
|
||||||
|
else
|
||||||
|
echo "warning: Scalar.NET uninstall script not found"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Re-create the Scalar symlink, in case it was removed by the Scalar.NET uninstall operation
|
||||||
|
mkdir -p $INSTALL_DST/bin
|
||||||
|
/bin/ln -Fs "$SCALAR_C_CMD" "$INSTALL_DST/bin/scalar"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Run Scalar cleanup (will exit if not applicable)
|
||||||
|
cleanupScalar
|
||||||
|
|
||||||
|
exit 0
|
|
@ -0,0 +1,34 @@
|
||||||
|
#!/bin/bash -e
|
||||||
|
if [ ! -r "/usr/local/git" ]; then
|
||||||
|
echo "Git doesn't appear to be installed via this installer. Aborting"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "$1" != "--yes" ]; then
|
||||||
|
echo "This will uninstall git by removing /usr/local/git/, and symlinks"
|
||||||
|
printf "Type 'yes' if you are sure you wish to continue: "
|
||||||
|
read response
|
||||||
|
else
|
||||||
|
response="yes"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "$response" == "yes" ]; then
|
||||||
|
# remove all of the symlinks we've created
|
||||||
|
pkgutil --files com.git.pkg | grep bin | while read f; do
|
||||||
|
if [ -L /usr/local/$f ]; then
|
||||||
|
sudo rm /usr/local/$f
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
# forget receipts.
|
||||||
|
pkgutil --packages | grep com.git.pkg | xargs -I {} sudo pkgutil --forget {}
|
||||||
|
echo "Uninstalled"
|
||||||
|
|
||||||
|
# The guts all go here.
|
||||||
|
sudo rm -rf /usr/local/git/
|
||||||
|
else
|
||||||
|
echo "Aborted"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
exit 0
|
|
@ -0,0 +1,135 @@
|
||||||
|
import argparse
|
||||||
|
import json
|
||||||
|
import os
|
||||||
|
import glob
|
||||||
|
import pprint
|
||||||
|
import subprocess
|
||||||
|
import sys
|
||||||
|
import re
|
||||||
|
|
||||||
|
parser = argparse.ArgumentParser(description='Sign binaries for macOS')
|
||||||
|
parser.add_argument('path', help='Path to file for signing')
|
||||||
|
parser.add_argument('keycode', help='Platform-specific key code for signing')
|
||||||
|
parser.add_argument('opcode', help='Platform-specific operation code for signing')
|
||||||
|
# Setting nargs=argparse.REMAINDER allows us to pass in params that begin with `--`
|
||||||
|
parser.add_argument('--params', nargs=argparse.REMAINDER, help='Parameters for signing')
|
||||||
|
args = parser.parse_args()
|
||||||
|
|
||||||
|
esrp_tool = os.path.join("esrp", "tools", "EsrpClient.exe")
|
||||||
|
|
||||||
|
aad_id = os.environ['AZURE_AAD_ID'].strip()
|
||||||
|
workspace = os.environ['GITHUB_WORKSPACE'].strip()
|
||||||
|
|
||||||
|
source_location = args.path
|
||||||
|
files = glob.glob(os.path.join(source_location, "*"))
|
||||||
|
|
||||||
|
print("Found files:")
|
||||||
|
pprint.pp(files)
|
||||||
|
|
||||||
|
auth_json = {
|
||||||
|
"Version": "1.0.0",
|
||||||
|
"AuthenticationType": "AAD_CERT",
|
||||||
|
"TenantId": "72f988bf-86f1-41af-91ab-2d7cd011db47",
|
||||||
|
"ClientId": f"{aad_id}",
|
||||||
|
"AuthCert": {
|
||||||
|
"SubjectName": f"CN={aad_id}.microsoft.com",
|
||||||
|
"StoreLocation": "LocalMachine",
|
||||||
|
"StoreName": "My",
|
||||||
|
"SendX5c" : "true"
|
||||||
|
},
|
||||||
|
"RequestSigningCert": {
|
||||||
|
"SubjectName": f"CN={aad_id}",
|
||||||
|
"StoreLocation": "LocalMachine",
|
||||||
|
"StoreName": "My"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
input_json = {
|
||||||
|
"Version": "1.0.0",
|
||||||
|
"SignBatches": [
|
||||||
|
{
|
||||||
|
"SourceLocationType": "UNC",
|
||||||
|
"SourceRootDirectory": source_location,
|
||||||
|
"DestinationLocationType": "UNC",
|
||||||
|
"DestinationRootDirectory": workspace,
|
||||||
|
"SignRequestFiles": [],
|
||||||
|
"SigningInfo": {
|
||||||
|
"Operations": [
|
||||||
|
{
|
||||||
|
"KeyCode": f"{args.keycode}",
|
||||||
|
"OperationCode": f"{args.opcode}",
|
||||||
|
"Parameters": {},
|
||||||
|
"ToolName": "sign",
|
||||||
|
"ToolVersion": "1.0",
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
# add files to sign
|
||||||
|
for f in files:
|
||||||
|
name = os.path.basename(f)
|
||||||
|
input_json["SignBatches"][0]["SignRequestFiles"].append(
|
||||||
|
{
|
||||||
|
"SourceLocation": name,
|
||||||
|
"DestinationLocation": os.path.join("signed", name),
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
# add parameters to input.json (e.g. enabling the hardened runtime for macOS)
|
||||||
|
if args.params is not None:
|
||||||
|
i = 0
|
||||||
|
while i < len(args.params):
|
||||||
|
input_json["SignBatches"][0]["SigningInfo"]["Operations"][0]["Parameters"][args.params[i]] = args.params[i + 1]
|
||||||
|
i += 2
|
||||||
|
|
||||||
|
policy_json = {
|
||||||
|
"Version": "1.0.0",
|
||||||
|
"Intent": "production release",
|
||||||
|
"ContentType": "binary",
|
||||||
|
}
|
||||||
|
|
||||||
|
configs = [
|
||||||
|
("auth.json", auth_json),
|
||||||
|
("input.json", input_json),
|
||||||
|
("policy.json", policy_json),
|
||||||
|
]
|
||||||
|
|
||||||
|
for filename, data in configs:
|
||||||
|
with open(filename, 'w') as fp:
|
||||||
|
json.dump(data, fp)
|
||||||
|
|
||||||
|
# Run ESRP Client
|
||||||
|
esrp_out = "esrp_out.json"
|
||||||
|
result = subprocess.run(
|
||||||
|
[esrp_tool, "sign",
|
||||||
|
"-a", "auth.json",
|
||||||
|
"-i", "input.json",
|
||||||
|
"-p", "policy.json",
|
||||||
|
"-o", esrp_out,
|
||||||
|
"-l", "Verbose"],
|
||||||
|
capture_output=True,
|
||||||
|
text=True,
|
||||||
|
cwd=workspace)
|
||||||
|
|
||||||
|
# Scrub log before printing
|
||||||
|
log = re.sub(r'^.+Uploading.*to\s*destinationUrl\s*(.+?),.+$',
|
||||||
|
'***',
|
||||||
|
result.stdout,
|
||||||
|
flags=re.IGNORECASE|re.MULTILINE)
|
||||||
|
print(log)
|
||||||
|
|
||||||
|
if result.returncode != 0:
|
||||||
|
print("Failed to run ESRPClient.exe")
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
if os.path.isfile(esrp_out):
|
||||||
|
print("ESRP output json:")
|
||||||
|
with open(esrp_out, 'r') as fp:
|
||||||
|
pprint.pp(json.load(fp))
|
||||||
|
|
||||||
|
for file in files:
|
||||||
|
if os.path.isfile(os.path.join("signed", file)):
|
||||||
|
print(f"Success!\nSigned {file}")
|
|
@ -0,0 +1,12 @@
|
||||||
|
# Install ESRP client
|
||||||
|
az storage blob download --file esrp.zip --auth-mode login --account-name esrpsigningstorage --container signing-resources --name microsoft.esrpclient.1.2.76.nupkg
|
||||||
|
Expand-Archive -Path esrp.zip -DestinationPath .\esrp
|
||||||
|
|
||||||
|
# Install certificates
|
||||||
|
az keyvault secret download --vault-name "$env:AZURE_VAULT" --name "$env:AUTH_CERT" --file out.pfx
|
||||||
|
certutil -f -importpfx out.pfx
|
||||||
|
Remove-Item out.pfx
|
||||||
|
|
||||||
|
az keyvault secret download --vault-name "$env:AZURE_VAULT" --name "$env:REQUEST_SIGNING_CERT" --file out.pfx
|
||||||
|
certutil -f -importpfx out.pfx
|
||||||
|
Remove-Item out.pfx
|
|
@ -0,0 +1,19 @@
|
||||||
|
#!/usr/bin/env ruby
|
||||||
|
|
||||||
|
install_prefix = ARGV[0]
|
||||||
|
puts install_prefix
|
||||||
|
git_binary = File.join(install_prefix, '/usr/local/git/bin/git')
|
||||||
|
|
||||||
|
[
|
||||||
|
['git' , File.join(install_prefix, '/usr/local/git/bin')],
|
||||||
|
['../../bin/git', File.join(install_prefix, '/usr/local/git/libexec/git-core')]
|
||||||
|
].each do |link, path|
|
||||||
|
Dir.glob(File.join(path, '*')).each do |file|
|
||||||
|
next if file == git_binary
|
||||||
|
puts "#{file} #{File.size(file)} == #{File.size(git_binary)}"
|
||||||
|
next unless File.size(file) == File.size(git_binary)
|
||||||
|
puts "Symlinking #{file}"
|
||||||
|
puts `ln -sf #{link} #{file}`
|
||||||
|
exit $?.exitstatus if $?.exitstatus != 0
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,787 @@
|
||||||
|
name: build-git-installers
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
tags:
|
||||||
|
- 'v[0-9]*vfs*' # matches "v<number><any characters>vfs<any characters>"
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
# Check prerequisites for the workflow
|
||||||
|
prereqs:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
env:
|
||||||
|
AZ_SUB: ${{ secrets.AZURE_SUBSCRIPTION }}
|
||||||
|
AZ_CREDS: ${{ secrets.AZURE_CREDENTIALS }}
|
||||||
|
outputs:
|
||||||
|
tag_name: ${{ steps.tag.outputs.name }} # The full name of the tag, e.g. v2.32.0.vfs.0.0
|
||||||
|
tag_version: ${{ steps.tag.outputs.version }} # The version number (without preceding "v"), e.g. 2.32.0.vfs.0.0
|
||||||
|
deb_signable: ${{ steps.deb.outputs.signable }} # Whether the credentials needed to sign the .deb package are available
|
||||||
|
steps:
|
||||||
|
- name: Determine tag to build
|
||||||
|
run: |
|
||||||
|
echo "name=${GITHUB_REF#refs/tags/}" >>$GITHUB_OUTPUT
|
||||||
|
echo "version=${GITHUB_REF#refs/tags/v}" >>$GITHUB_OUTPUT
|
||||||
|
id: tag
|
||||||
|
- name: Determine whether signing certificates are present
|
||||||
|
run: echo "signable=$([[ $AZ_SUB != '' && $AZ_CREDS != '' ]] && echo 'true' || echo 'false')" >>$GITHUB_OUTPUT
|
||||||
|
id: deb
|
||||||
|
- name: Clone git
|
||||||
|
uses: actions/checkout@v3
|
||||||
|
- name: Validate the tag identified with trigger
|
||||||
|
run: |
|
||||||
|
die () {
|
||||||
|
echo "::error::$*" >&2
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
# `actions/checkout` only downloads the peeled tag (i.e. the commit)
|
||||||
|
git fetch origin +$GITHUB_REF:$GITHUB_REF
|
||||||
|
|
||||||
|
# Verify that the tag is annotated
|
||||||
|
test $(git cat-file -t "$GITHUB_REF") == "tag" || die "Tag ${{ steps.tag.outputs.name }} is not annotated"
|
||||||
|
|
||||||
|
# Verify tag follows rules in GIT-VERSION-GEN (i.e., matches the specified "DEF_VER" in
|
||||||
|
# GIT-VERSION-FILE) and matches tag determined from trigger
|
||||||
|
make GIT-VERSION-FILE
|
||||||
|
test "${{ steps.tag.outputs.version }}" == "$(sed -n 's/^GIT_VERSION = //p'< GIT-VERSION-FILE)" || die "GIT-VERSION-FILE tag does not match ${{ steps.tag.outputs.name }}"
|
||||||
|
# End check prerequisites for the workflow
|
||||||
|
|
||||||
|
# Build Windows installers (x86_64 installer & portable)
|
||||||
|
windows_pkg:
|
||||||
|
runs-on: windows-2019
|
||||||
|
needs: prereqs
|
||||||
|
env:
|
||||||
|
GPG_OPTIONS: "--batch --yes --no-tty --list-options no-show-photos --verify-options no-show-photos --pinentry-mode loopback"
|
||||||
|
HOME: "${{github.workspace}}\\home"
|
||||||
|
USERPROFILE: "${{github.workspace}}\\home"
|
||||||
|
steps:
|
||||||
|
- name: Configure user
|
||||||
|
shell: bash
|
||||||
|
run:
|
||||||
|
USER_NAME="${{github.actor}}" &&
|
||||||
|
USER_EMAIL="${{github.actor}}@users.noreply.github.com" &&
|
||||||
|
mkdir -p "$HOME" &&
|
||||||
|
git config --global user.name "$USER_NAME" &&
|
||||||
|
git config --global user.email "$USER_EMAIL" &&
|
||||||
|
echo "PACKAGER=$USER_NAME <$USER_EMAIL>" >>$GITHUB_ENV
|
||||||
|
- uses: git-for-windows/setup-git-for-windows-sdk@v1
|
||||||
|
with:
|
||||||
|
flavor: build-installers
|
||||||
|
- name: Clone build-extra
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
git clone --filter=blob:none --single-branch -b main https://github.com/git-for-windows/build-extra /usr/src/build-extra
|
||||||
|
- name: Clone git
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
# Since we cannot directly clone a specified tag (as we would a branch with `git clone -b <branch name>`),
|
||||||
|
# this clone has to be done manually (via init->fetch->reset).
|
||||||
|
|
||||||
|
tag_name="${{ needs.prereqs.outputs.tag_name }}" &&
|
||||||
|
git -c init.defaultBranch=main init &&
|
||||||
|
git remote add -f origin https://github.com/git-for-windows/git &&
|
||||||
|
git fetch "https://github.com/${{github.repository}}" refs/tags/${tag_name}:refs/tags/${tag_name} &&
|
||||||
|
git reset --hard ${tag_name}
|
||||||
|
- name: Prepare home directory for code-signing
|
||||||
|
env:
|
||||||
|
CODESIGN_P12: ${{secrets.CODESIGN_P12}}
|
||||||
|
CODESIGN_PASS: ${{secrets.CODESIGN_PASS}}
|
||||||
|
if: env.CODESIGN_P12 != '' && env.CODESIGN_PASS != ''
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
cd home &&
|
||||||
|
mkdir -p .sig &&
|
||||||
|
echo -n "$CODESIGN_P12" | tr % '\n' | base64 -d >.sig/codesign.p12 &&
|
||||||
|
echo -n "$CODESIGN_PASS" >.sig/codesign.pass
|
||||||
|
git config --global alias.signtool '!sh "/usr/src/build-extra/signtool.sh"'
|
||||||
|
- name: Prepare home directory for GPG signing
|
||||||
|
if: env.GPGKEY != ''
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
# This section ensures that the identity for the GPG key matches the git user identity, otherwise
|
||||||
|
# signing will fail
|
||||||
|
|
||||||
|
echo '${{secrets.PRIVGPGKEY}}' | tr % '\n' | gpg $GPG_OPTIONS --import &&
|
||||||
|
info="$(gpg --list-keys --with-colons "${GPGKEY%% *}" | cut -d : -f 1,10 | sed -n '/^uid/{s|uid:||p;q}')" &&
|
||||||
|
git config --global user.name "${info% <*}" &&
|
||||||
|
git config --global user.email "<${info#*<}"
|
||||||
|
env:
|
||||||
|
GPGKEY: ${{secrets.GPGKEY}}
|
||||||
|
- name: Build mingw-w64-x86_64-git
|
||||||
|
env:
|
||||||
|
GPGKEY: "${{secrets.GPGKEY}}"
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
set -x
|
||||||
|
|
||||||
|
# Make sure that there is a `/usr/bin/git` that can be used by `makepkg-mingw`
|
||||||
|
printf '#!/bin/sh\n\nexec /mingw64/bin/git.exe "$@"\n' >/usr/bin/git &&
|
||||||
|
|
||||||
|
# Restrict `PATH` to MSYS2 and to Visual Studio (to let `cv2pdb` find the relevant DLLs)
|
||||||
|
PATH="/mingw64/bin:/usr/bin:/C/Program Files (x86)/Microsoft Visual Studio 14.0/VC/bin/amd64:/C/Windows/system32"
|
||||||
|
|
||||||
|
type -p mspdb140.dll || exit 1
|
||||||
|
|
||||||
|
sh -x /usr/src/build-extra/please.sh build-mingw-w64-git --only-64-bit --build-src-pkg -o artifacts HEAD &&
|
||||||
|
if test -n "$GPGKEY"
|
||||||
|
then
|
||||||
|
for tar in artifacts/*.tar*
|
||||||
|
do
|
||||||
|
/usr/src/build-extra/gnupg-with-gpgkey.sh --detach-sign --no-armor $tar
|
||||||
|
done
|
||||||
|
fi &&
|
||||||
|
|
||||||
|
b=$PWD/artifacts &&
|
||||||
|
version=${{ needs.prereqs.outputs.tag_name }} &&
|
||||||
|
(cd /usr/src/MINGW-packages/mingw-w64-git &&
|
||||||
|
cp PKGBUILD.$version PKGBUILD &&
|
||||||
|
git commit -s -m "mingw-w64-git: new version ($version)" PKGBUILD &&
|
||||||
|
git bundle create "$b"/MINGW-packages.bundle origin/main..main)
|
||||||
|
- name: Publish mingw-w64-x86_64-git
|
||||||
|
uses: actions/upload-artifact@v3
|
||||||
|
with:
|
||||||
|
name: pkg-x86_64
|
||||||
|
path: artifacts
|
||||||
|
windows_artifacts:
|
||||||
|
runs-on: windows-2019
|
||||||
|
needs: [prereqs, windows_pkg]
|
||||||
|
env:
|
||||||
|
HOME: "${{github.workspace}}\\home"
|
||||||
|
strategy:
|
||||||
|
matrix:
|
||||||
|
artifact:
|
||||||
|
- name: installer
|
||||||
|
fileprefix: Git
|
||||||
|
- name: portable
|
||||||
|
fileprefix: PortableGit
|
||||||
|
fail-fast: false
|
||||||
|
steps:
|
||||||
|
- name: Download pkg-x86_64
|
||||||
|
uses: actions/download-artifact@v3
|
||||||
|
with:
|
||||||
|
name: pkg-x86_64
|
||||||
|
path: pkg-x86_64
|
||||||
|
- uses: git-for-windows/setup-git-for-windows-sdk@v1
|
||||||
|
with:
|
||||||
|
flavor: build-installers
|
||||||
|
- name: Clone build-extra
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
git clone --filter=blob:none --single-branch -b main https://github.com/git-for-windows/build-extra /usr/src/build-extra
|
||||||
|
- name: Prepare home directory for code-signing
|
||||||
|
env:
|
||||||
|
CODESIGN_P12: ${{secrets.CODESIGN_P12}}
|
||||||
|
CODESIGN_PASS: ${{secrets.CODESIGN_PASS}}
|
||||||
|
if: env.CODESIGN_P12 != '' && env.CODESIGN_PASS != ''
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
mkdir -p home/.sig &&
|
||||||
|
echo -n "$CODESIGN_P12" | tr % '\n' | base64 -d >home/.sig/codesign.p12 &&
|
||||||
|
echo -n "$CODESIGN_PASS" >home/.sig/codesign.pass &&
|
||||||
|
git config --global alias.signtool '!sh "/usr/src/build-extra/signtool.sh"'
|
||||||
|
- name: Retarget auto-update to microsoft/git
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
set -x
|
||||||
|
|
||||||
|
b=/usr/src/build-extra &&
|
||||||
|
|
||||||
|
filename=$b/git-update-git-for-windows.config
|
||||||
|
tr % '\t' >$filename <<-\EOF &&
|
||||||
|
[update]
|
||||||
|
%fromFork = microsoft/git
|
||||||
|
EOF
|
||||||
|
|
||||||
|
sed -i -e '/^#include "file-list.iss"/a\
|
||||||
|
Source: {#SourcePath}\\..\\git-update-git-for-windows.config; DestDir: {app}\\mingw64\\bin; Flags: replacesameversion; AfterInstall: DeleteFromVirtualStore' \
|
||||||
|
-e '/^Type: dirifempty; Name: {app}\\{#MINGW_BITNESS}$/i\
|
||||||
|
Type: files; Name: {app}\\{#MINGW_BITNESS}\\bin\\git-update-git-for-windows.config\
|
||||||
|
Type: dirifempty; Name: {app}\\{#MINGW_BITNESS}\\bin' \
|
||||||
|
$b/installer/install.iss
|
||||||
|
- name: Set alerts to continue until upgrade is taken
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
set -x
|
||||||
|
|
||||||
|
b=/mingw64/bin &&
|
||||||
|
|
||||||
|
sed -i -e '6 a use_recently_seen=no' \
|
||||||
|
$b/git-update-git-for-windows
|
||||||
|
- name: Set the installer Publisher to the Git Fundamentals team
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
b=/usr/src/build-extra &&
|
||||||
|
sed -i -e 's/^\(AppPublisher=\).*/\1The Git Fundamentals Team at GitHub/' $b/installer/install.iss
|
||||||
|
- name: Let the installer configure Visual Studio to use the installed Git
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
set -x
|
||||||
|
|
||||||
|
b=/usr/src/build-extra &&
|
||||||
|
|
||||||
|
sed -i -e '/^ *InstallAutoUpdater();$/a\
|
||||||
|
CustomPostInstall();' \
|
||||||
|
-e '/^ *UninstallAutoUpdater();$/a\
|
||||||
|
CustomPostUninstall();' \
|
||||||
|
$b/installer/install.iss &&
|
||||||
|
|
||||||
|
cat >>$b/installer/helpers.inc.iss <<\EOF
|
||||||
|
|
||||||
|
procedure CustomPostInstall();
|
||||||
|
begin
|
||||||
|
if not RegWriteStringValue(HKEY_CURRENT_USER,'Software\Microsoft\VSCommon\15.0\TeamFoundation\GitSourceControl','GitPath',ExpandConstant('{app}')) or
|
||||||
|
not RegWriteStringValue(HKEY_CURRENT_USER,'Software\Microsoft\VSCommon\16.0\TeamFoundation\GitSourceControl','GitPath',ExpandConstant('{app}')) or
|
||||||
|
not RegWriteStringValue(HKEY_CURRENT_USER,'Software\Microsoft\VSCommon\17.0\TeamFoundation\GitSourceControl','GitPath',ExpandConstant('{app}')) or
|
||||||
|
not RegWriteStringValue(HKEY_CURRENT_USER,'Software\Microsoft\VSCommon\18.0\TeamFoundation\GitSourceControl','GitPath',ExpandConstant('{app}')) or
|
||||||
|
not RegWriteStringValue(HKEY_CURRENT_USER,'Software\Microsoft\VSCommon\19.0\TeamFoundation\GitSourceControl','GitPath',ExpandConstant('{app}')) or
|
||||||
|
not RegWriteStringValue(HKEY_CURRENT_USER,'Software\Microsoft\VSCommon\20.0\TeamFoundation\GitSourceControl','GitPath',ExpandConstant('{app}')) then
|
||||||
|
LogError('Could not register TeamFoundation\GitSourceControl');
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure CustomPostUninstall();
|
||||||
|
begin
|
||||||
|
if not RegDeleteValue(HKEY_CURRENT_USER,'Software\Microsoft\VSCommon\15.0\TeamFoundation\GitSourceControl','GitPath') or
|
||||||
|
not RegDeleteValue(HKEY_CURRENT_USER,'Software\Microsoft\VSCommon\16.0\TeamFoundation\GitSourceControl','GitPath') or
|
||||||
|
not RegDeleteValue(HKEY_CURRENT_USER,'Software\Microsoft\VSCommon\17.0\TeamFoundation\GitSourceControl','GitPath') or
|
||||||
|
not RegDeleteValue(HKEY_CURRENT_USER,'Software\Microsoft\VSCommon\18.0\TeamFoundation\GitSourceControl','GitPath') or
|
||||||
|
not RegDeleteValue(HKEY_CURRENT_USER,'Software\Microsoft\VSCommon\19.0\TeamFoundation\GitSourceControl','GitPath') or
|
||||||
|
not RegDeleteValue(HKEY_CURRENT_USER,'Software\Microsoft\VSCommon\20.0\TeamFoundation\GitSourceControl','GitPath') then
|
||||||
|
LogError('Could not register TeamFoundation\GitSourceControl');
|
||||||
|
end;
|
||||||
|
EOF
|
||||||
|
- name: Enable Scalar/C and the auto-updater in the installer by default
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
set -x
|
||||||
|
|
||||||
|
b=/usr/src/build-extra &&
|
||||||
|
|
||||||
|
sed -i -e "/ChosenOptions:=''/a\\
|
||||||
|
if (ExpandConstant('{param:components|/}')='/') then begin\n\
|
||||||
|
WizardSelectComponents('autoupdate');\n\
|
||||||
|
#ifdef WITH_SCALAR\n\
|
||||||
|
WizardSelectComponents('scalar');\n\
|
||||||
|
#endif\n\
|
||||||
|
end;" $b/installer/install.iss
|
||||||
|
- name: Build 64-bit ${{matrix.artifact.name}}
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
set -x
|
||||||
|
|
||||||
|
# Copy the PDB archive to the directory where `--include-pdbs` expects it
|
||||||
|
b=/usr/src/build-extra &&
|
||||||
|
mkdir -p $b/cached-source-packages &&
|
||||||
|
cp pkg-x86_64/*-pdb* $b/cached-source-packages/ &&
|
||||||
|
|
||||||
|
# Build the installer, embedding PDBs
|
||||||
|
eval $b/please.sh make_installers_from_mingw_w64_git --include-pdbs \
|
||||||
|
--version=${{ needs.prereqs.outputs.tag_version }} \
|
||||||
|
-o artifacts --${{matrix.artifact.name}} \
|
||||||
|
--pkg=pkg-x86_64/mingw-w64-x86_64-git-[0-9]*.tar.xz \
|
||||||
|
--pkg=pkg-x86_64/mingw-w64-x86_64-git-doc-html-[0-9]*.tar.xz &&
|
||||||
|
|
||||||
|
if test portable = '${{matrix.artifact.name}}' && test -n "$(git config alias.signtool)"
|
||||||
|
then
|
||||||
|
git signtool artifacts/PortableGit-*.exe
|
||||||
|
fi &&
|
||||||
|
openssl dgst -sha256 artifacts/${{matrix.artifact.fileprefix}}-*.exe | sed "s/.* //" >artifacts/sha-256.txt
|
||||||
|
- name: Verify that .exe files are code-signed
|
||||||
|
if: env.CODESIGN_P12 != '' && env.CODESIGN_PASS != ''
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
PATH=$PATH:"/c/Program Files (x86)/Windows Kits/10/App Certification Kit/" \
|
||||||
|
signtool verify //pa artifacts/${{matrix.artifact.fileprefix}}-*.exe
|
||||||
|
- name: Publish ${{matrix.artifact.name}}-x86_64
|
||||||
|
uses: actions/upload-artifact@v3
|
||||||
|
with:
|
||||||
|
name: win-${{matrix.artifact.name}}-x86_64
|
||||||
|
path: artifacts
|
||||||
|
# End build Windows installers
|
||||||
|
|
||||||
|
# Build and sign Mac OSX installers & upload artifacts
|
||||||
|
osx_build:
|
||||||
|
runs-on: macos-latest
|
||||||
|
needs: prereqs
|
||||||
|
env:
|
||||||
|
# `gettext` is keg-only
|
||||||
|
LDFLAGS: -L/usr/local/opt/gettext/lib
|
||||||
|
CFLAGS: -I/usr/local/opt/gettext/include
|
||||||
|
# To make use of the catalogs...
|
||||||
|
XML_CATALOG_FILES: /usr/local/etc/xml/catalog
|
||||||
|
VERSION: "${{ needs.prereqs.outputs.tag_version }}"
|
||||||
|
steps:
|
||||||
|
- name: Check out repository
|
||||||
|
uses: actions/checkout@v3
|
||||||
|
with:
|
||||||
|
path: 'git'
|
||||||
|
|
||||||
|
- name: Install Git dependencies
|
||||||
|
run: |
|
||||||
|
set -x
|
||||||
|
brew install automake asciidoc xmlto docbook
|
||||||
|
brew link --force gettext
|
||||||
|
|
||||||
|
- name: Build payload
|
||||||
|
run: |
|
||||||
|
# Configure the environment
|
||||||
|
set -x
|
||||||
|
PATH=/usr/local/bin:$PATH
|
||||||
|
export CURL_LDFLAGS=$(curl-config --libs)
|
||||||
|
|
||||||
|
# Write to "version" file to force match with trigger payload version
|
||||||
|
echo "${{ needs.prereqs.outputs.tag_version }}" >>git/version
|
||||||
|
make -C git -j$(sysctl -n hw.physicalcpu) GIT-VERSION-FILE dist dist-doc
|
||||||
|
|
||||||
|
# Extract tarballs
|
||||||
|
mkdir payload manpages
|
||||||
|
tar -xvf git/git-$VERSION.tar.gz -C payload
|
||||||
|
tar -xvf git/git-manpages-$VERSION.tar.gz -C manpages
|
||||||
|
|
||||||
|
# Lay out payload
|
||||||
|
make -C git/.github/macos-installer V=1 payload
|
||||||
|
|
||||||
|
# This step is necessary because we cannot use the $VERSION
|
||||||
|
# environment variable or the tag_version output from the prereqs
|
||||||
|
# job in the upload-artifact task.
|
||||||
|
mkdir -p build_artifacts
|
||||||
|
cp -R stage/git-intel-x86_64-$VERSION/ build_artifacts
|
||||||
|
|
||||||
|
# We keep a list of executable files because their executable bits are
|
||||||
|
# removed when they are zipped, and we need to re-add.
|
||||||
|
find build_artifacts -type f -a -perm -u=x >executable-files.txt
|
||||||
|
|
||||||
|
- name: Upload macOS artifacts
|
||||||
|
uses: actions/upload-artifact@v3
|
||||||
|
with:
|
||||||
|
name: tmp.osx-build
|
||||||
|
path: |
|
||||||
|
build_artifacts
|
||||||
|
|
||||||
|
- name: Upload list of executable files
|
||||||
|
uses: actions/upload-artifact@v3
|
||||||
|
with:
|
||||||
|
name: tmp.executable-files
|
||||||
|
path: |
|
||||||
|
executable-files.txt
|
||||||
|
|
||||||
|
osx_sign_payload:
|
||||||
|
# ESRP service requires signing to run on Windows
|
||||||
|
runs-on: windows-latest
|
||||||
|
needs: osx_build
|
||||||
|
steps:
|
||||||
|
- name: Check out repository
|
||||||
|
uses: actions/checkout@v3
|
||||||
|
with:
|
||||||
|
path: 'git'
|
||||||
|
|
||||||
|
- name: Download unsigned build artifiacts
|
||||||
|
uses: actions/download-artifact@v3
|
||||||
|
with:
|
||||||
|
name: tmp.osx-build
|
||||||
|
path: build_artifacts
|
||||||
|
|
||||||
|
- name: Zip unsigned build artifacts
|
||||||
|
shell: pwsh
|
||||||
|
run: |
|
||||||
|
Compress-Archive -Path build_artifacts build_artifacts/build_artifacts.zip
|
||||||
|
cd build_artifacts
|
||||||
|
Get-ChildItem -Exclude build_artifacts.zip | Remove-Item -Recurse -Force
|
||||||
|
|
||||||
|
- uses: azure/login@v1
|
||||||
|
with:
|
||||||
|
creds: ${{ secrets.AZURE_CREDENTIALS }}
|
||||||
|
|
||||||
|
- name: Set up ESRP client
|
||||||
|
shell: pwsh
|
||||||
|
env:
|
||||||
|
AZURE_VAULT: ${{ secrets.AZURE_VAULT }}
|
||||||
|
AUTH_CERT: ${{ secrets.AZURE_VAULT_AUTH_CERT_NAME }}
|
||||||
|
REQUEST_SIGNING_CERT: ${{ secrets.AZURE_VAULT_REQUEST_SIGNING_CERT_NAME }}
|
||||||
|
run: |
|
||||||
|
git\.github\scripts\set-up-esrp.ps1
|
||||||
|
|
||||||
|
- name: Run ESRP client
|
||||||
|
shell: pwsh
|
||||||
|
env:
|
||||||
|
AZURE_AAD_ID: ${{ secrets.AZURE_AAD_ID }}
|
||||||
|
APPLE_KEY_CODE: ${{ secrets.APPLE_KEY_CODE }}
|
||||||
|
APPLE_SIGNING_OP_CODE: ${{ secrets.APPLE_SIGNING_OPERATION_CODE }}
|
||||||
|
run: |
|
||||||
|
python git\.github\scripts\run-esrp-signing.py build_artifacts `
|
||||||
|
$env:APPLE_KEY_CODE $env:APPLE_SIGNING_OP_CODE `
|
||||||
|
--params 'Hardening' '--options=runtime'
|
||||||
|
|
||||||
|
- name: Unzip signed build artifacts
|
||||||
|
shell: pwsh
|
||||||
|
run: |
|
||||||
|
Expand-Archive signed/build_artifacts.zip -DestinationPath signed
|
||||||
|
Remove-Item signed/build_artifacts.zip
|
||||||
|
|
||||||
|
- name: Upload signed payload
|
||||||
|
uses: actions/upload-artifact@v3
|
||||||
|
with:
|
||||||
|
name: osx-signed-payload
|
||||||
|
path: |
|
||||||
|
signed
|
||||||
|
|
||||||
|
osx_pack:
|
||||||
|
runs-on: macos-latest
|
||||||
|
needs: [prereqs, osx_sign_payload]
|
||||||
|
steps:
|
||||||
|
- name: Check out repository
|
||||||
|
uses: actions/checkout@v3
|
||||||
|
with:
|
||||||
|
path: 'git'
|
||||||
|
|
||||||
|
- name: Download signed artifacts
|
||||||
|
uses: actions/download-artifact@v3
|
||||||
|
with:
|
||||||
|
name: osx-signed-payload
|
||||||
|
|
||||||
|
- name: Download list of executable files
|
||||||
|
uses: actions/download-artifact@v3
|
||||||
|
with:
|
||||||
|
name: tmp.executable-files
|
||||||
|
|
||||||
|
- name: Build macOS pkg
|
||||||
|
env:
|
||||||
|
VERSION: "${{ needs.prereqs.outputs.tag_version }}"
|
||||||
|
run: |
|
||||||
|
# Install findutils to use gxargs below
|
||||||
|
brew install findutils
|
||||||
|
|
||||||
|
# Configure the environment
|
||||||
|
export CURL_LDFLAGS=$(curl-config --libs)
|
||||||
|
|
||||||
|
# Add executable bits and move build_artifacts into
|
||||||
|
# the same directory as Makefile (so that executable bits
|
||||||
|
# will be recognized).
|
||||||
|
gxargs -r -d '\n' chmod a+x <executable-files.txt
|
||||||
|
mv build_artifacts git/.github/macos-installer/
|
||||||
|
|
||||||
|
# Create pkg
|
||||||
|
PATH=/usr/local/bin:$PATH \
|
||||||
|
make -C git/.github/macos-installer V=1 pkg ||
|
||||||
|
die "Build failed"
|
||||||
|
|
||||||
|
- name: Upload unsigned pkg
|
||||||
|
uses: actions/upload-artifact@v3
|
||||||
|
with:
|
||||||
|
name: tmp.osx-pkg
|
||||||
|
path: |
|
||||||
|
git/.github/macos-installer/disk-image
|
||||||
|
|
||||||
|
osx_sign_and_notarize_pkg:
|
||||||
|
# ESRP service requires signing to run on Windows
|
||||||
|
runs-on: windows-latest
|
||||||
|
needs: osx_pack
|
||||||
|
steps:
|
||||||
|
- name: Check out repository
|
||||||
|
uses: actions/checkout@v3
|
||||||
|
with:
|
||||||
|
path: 'git'
|
||||||
|
|
||||||
|
- name: Download unsigned package
|
||||||
|
uses: actions/download-artifact@v3
|
||||||
|
with:
|
||||||
|
name: tmp.osx-pkg
|
||||||
|
path: pkg
|
||||||
|
|
||||||
|
- name: Zip unsigned package
|
||||||
|
shell: pwsh
|
||||||
|
run: |
|
||||||
|
Compress-Archive -Path pkg/*.pkg pkg/msft-git-pkg.zip
|
||||||
|
cd pkg
|
||||||
|
Get-ChildItem -Exclude msft-git-pkg.zip | Remove-Item -Recurse -Force
|
||||||
|
|
||||||
|
- uses: azure/login@v1
|
||||||
|
with:
|
||||||
|
creds: ${{ secrets.AZURE_CREDENTIALS }}
|
||||||
|
|
||||||
|
- name: Set up ESRP client
|
||||||
|
shell: pwsh
|
||||||
|
env:
|
||||||
|
AZURE_VAULT: ${{ secrets.AZURE_VAULT }}
|
||||||
|
AUTH_CERT: ${{ secrets.AZURE_VAULT_AUTH_CERT_NAME }}
|
||||||
|
REQUEST_SIGNING_CERT: ${{ secrets.AZURE_VAULT_REQUEST_SIGNING_CERT_NAME }}
|
||||||
|
run: |
|
||||||
|
git\.github\scripts\set-up-esrp.ps1
|
||||||
|
|
||||||
|
- name: Sign package
|
||||||
|
shell: pwsh
|
||||||
|
env:
|
||||||
|
AZURE_AAD_ID: ${{ secrets.AZURE_AAD_ID }}
|
||||||
|
APPLE_KEY_CODE: ${{ secrets.APPLE_KEY_CODE }}
|
||||||
|
APPLE_SIGNING_OP_CODE: ${{ secrets.APPLE_SIGNING_OPERATION_CODE }}
|
||||||
|
run: |
|
||||||
|
python git\.github\scripts\run-esrp-signing.py pkg $env:APPLE_KEY_CODE $env:APPLE_SIGNING_OP_CODE
|
||||||
|
|
||||||
|
- name: Unzip signed package
|
||||||
|
shell: pwsh
|
||||||
|
run: |
|
||||||
|
mkdir unsigned
|
||||||
|
Expand-Archive -LiteralPath signed\msft-git-pkg.zip -DestinationPath .\unsigned -Force
|
||||||
|
Remove-Item signed\msft-git-pkg.zip -Force
|
||||||
|
|
||||||
|
- name: Notarize signed package
|
||||||
|
shell: pwsh
|
||||||
|
env:
|
||||||
|
AZURE_AAD_ID: ${{ secrets.AZURE_AAD_ID }}
|
||||||
|
APPLE_KEY_CODE: ${{ secrets.APPLE_KEY_CODE }}
|
||||||
|
APPLE_NOTARIZATION_OP_CODE: ${{ secrets.APPLE_NOTARIZATION_OPERATION_CODE }}
|
||||||
|
run: |
|
||||||
|
python git\.github\scripts\run-esrp-signing.py unsigned $env:APPLE_KEY_CODE `
|
||||||
|
$env:APPLE_NOTARIZATION_OP_CODE --params 'BundleId' 'com.microsoft.git'
|
||||||
|
|
||||||
|
- name: Upload signed and notarized pkg
|
||||||
|
uses: actions/upload-artifact@v3
|
||||||
|
with:
|
||||||
|
name: osx-signed-pkg
|
||||||
|
path: |
|
||||||
|
signed
|
||||||
|
|
||||||
|
osx_publish_dmg:
|
||||||
|
runs-on: macos-latest
|
||||||
|
needs: [prereqs, osx_sign_and_notarize_pkg]
|
||||||
|
steps:
|
||||||
|
- name: Check out repository
|
||||||
|
uses: actions/checkout@v3
|
||||||
|
with:
|
||||||
|
path: 'git'
|
||||||
|
|
||||||
|
- name: Download signed package
|
||||||
|
uses: actions/download-artifact@v3
|
||||||
|
with:
|
||||||
|
name: osx-signed-pkg
|
||||||
|
path: disk-image
|
||||||
|
|
||||||
|
- name: Build macOS disk image
|
||||||
|
env:
|
||||||
|
VERSION: "${{ needs.prereqs.outputs.tag_version }}"
|
||||||
|
run: |
|
||||||
|
# Move disk-image into the same directory as Makefile
|
||||||
|
mv disk-image git/.github/macos-installer/
|
||||||
|
|
||||||
|
PATH=/usr/local/bin:$PATH \
|
||||||
|
make -C git/.github/macos-installer V=1 image || die "Build failed"
|
||||||
|
|
||||||
|
- name: Publish disk image
|
||||||
|
uses: actions/upload-artifact@v3
|
||||||
|
with:
|
||||||
|
name: osx-dmg
|
||||||
|
path: git/.github/macos-installer/*.dmg
|
||||||
|
# End build and sign Mac OSX installers
|
||||||
|
|
||||||
|
# Build & sign Ubuntu package
|
||||||
|
ubuntu_build:
|
||||||
|
runs-on: ubuntu-20.04
|
||||||
|
needs: prereqs
|
||||||
|
steps:
|
||||||
|
- name: Install git dependencies
|
||||||
|
run: |
|
||||||
|
set -ex
|
||||||
|
|
||||||
|
sudo apt-get update -q
|
||||||
|
sudo apt-get install -y -q --no-install-recommends gettext libcurl4-gnutls-dev libpcre3-dev asciidoc xmlto
|
||||||
|
- name: Clone git
|
||||||
|
uses: actions/checkout@v3
|
||||||
|
with:
|
||||||
|
path: git
|
||||||
|
- name: Build and package .deb
|
||||||
|
run: |
|
||||||
|
set -ex
|
||||||
|
|
||||||
|
die () {
|
||||||
|
echo "$*" >&2
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
echo "${{ needs.prereqs.outputs.tag_version }}" >>git/version
|
||||||
|
make -C git GIT-VERSION-FILE
|
||||||
|
|
||||||
|
VERSION="${{ needs.prereqs.outputs.tag_version }}"
|
||||||
|
|
||||||
|
ARCH="$(dpkg-architecture -q DEB_HOST_ARCH)"
|
||||||
|
if test -z "$ARCH"; then
|
||||||
|
die "Could not determine host architecture!"
|
||||||
|
fi
|
||||||
|
|
||||||
|
PKGNAME="microsoft-git_$VERSION"
|
||||||
|
PKGDIR="$(dirname $(pwd))/$PKGNAME"
|
||||||
|
|
||||||
|
rm -rf "$PKGDIR"
|
||||||
|
mkdir -p "$PKGDIR"
|
||||||
|
|
||||||
|
DESTDIR="$PKGDIR" make -C git -j5 V=1 DEVELOPER=1 \
|
||||||
|
USE_LIBPCRE=1 \
|
||||||
|
NO_CROSS_DIRECTORY_HARDLINKS=1 \
|
||||||
|
ASCIIDOC8=1 ASCIIDOC_NO_ROFF=1 \
|
||||||
|
ASCIIDOC='TZ=UTC asciidoc' \
|
||||||
|
prefix=/usr/local \
|
||||||
|
gitexecdir=/usr/local/lib/git-core \
|
||||||
|
libexecdir=/usr/local/lib/git-core \
|
||||||
|
htmldir=/usr/local/share/doc/git/html \
|
||||||
|
install install-doc install-html
|
||||||
|
|
||||||
|
cd ..
|
||||||
|
mkdir "$PKGNAME/DEBIAN"
|
||||||
|
|
||||||
|
# Based on https://packages.ubuntu.com/xenial/vcs/git
|
||||||
|
cat >"$PKGNAME/DEBIAN/control" <<EOF
|
||||||
|
Package: microsoft-git
|
||||||
|
Version: $VERSION
|
||||||
|
Section: vcs
|
||||||
|
Priority: optional
|
||||||
|
Architecture: $ARCH
|
||||||
|
Depends: libcurl3-gnutls, liberror-perl, libexpat1, libpcre2-8-0, perl, perl-modules, zlib1g
|
||||||
|
Maintainer: Git Fundamentals <git-fundamentals@github.com>
|
||||||
|
Description: Git client built from the https://github.com/microsoft/git repository,
|
||||||
|
specialized in supporting monorepo scenarios. Includes the Scalar CLI.
|
||||||
|
EOF
|
||||||
|
|
||||||
|
dpkg-deb --build "$PKGNAME"
|
||||||
|
|
||||||
|
mkdir $GITHUB_WORKSPACE/artifacts
|
||||||
|
mv "$PKGNAME.deb" $GITHUB_WORKSPACE/artifacts/
|
||||||
|
- name: Publish unsigned .deb package
|
||||||
|
uses: actions/upload-artifact@v3
|
||||||
|
with:
|
||||||
|
name: deb-package-unsigned
|
||||||
|
path: artifacts/
|
||||||
|
ubuntu_sign-artifacts:
|
||||||
|
runs-on: windows-latest # Must be run on Windows due to ESRP executable OS compatibility
|
||||||
|
needs: [ubuntu_build, prereqs]
|
||||||
|
if: needs.prereqs.outputs.deb_signable == 'true'
|
||||||
|
env:
|
||||||
|
ARTIFACTS_DIR: artifacts
|
||||||
|
steps:
|
||||||
|
- name: Clone repository
|
||||||
|
uses: actions/checkout@v3
|
||||||
|
with:
|
||||||
|
path: 'git'
|
||||||
|
- name: Download unsigned packages
|
||||||
|
uses: actions/download-artifact@v3
|
||||||
|
with:
|
||||||
|
name: deb-package-unsigned
|
||||||
|
path: unsigned
|
||||||
|
- uses: azure/login@v1
|
||||||
|
with:
|
||||||
|
creds: ${{ secrets.AZURE_CREDENTIALS }}
|
||||||
|
- name: Set up ESRP client
|
||||||
|
shell: pwsh
|
||||||
|
env:
|
||||||
|
AZURE_VAULT: ${{ secrets.AZURE_VAULT }}
|
||||||
|
AUTH_CERT: ${{ secrets.AZURE_VAULT_AUTH_CERT_NAME }}
|
||||||
|
REQUEST_SIGNING_CERT: ${{ secrets.AZURE_VAULT_REQUEST_SIGNING_CERT_NAME }}
|
||||||
|
run: |
|
||||||
|
git\.github\scripts\set-up-esrp.ps1
|
||||||
|
- name: Sign package
|
||||||
|
shell: pwsh
|
||||||
|
env:
|
||||||
|
AZURE_AAD_ID: ${{ secrets.AZURE_AAD_ID }}
|
||||||
|
LINUX_KEY_CODE: ${{ secrets.LINUX_KEY_CODE }}
|
||||||
|
LINUX_OP_CODE: ${{ secrets.LINUX_OPERATION_CODE }}
|
||||||
|
run: |
|
||||||
|
python git\.github\scripts\run-esrp-signing.py unsigned $env:LINUX_KEY_CODE $env:LINUX_OP_CODE
|
||||||
|
- name: Upload signed artifact
|
||||||
|
uses: actions/upload-artifact@v3
|
||||||
|
with:
|
||||||
|
name: deb-package-signed
|
||||||
|
path: signed
|
||||||
|
# End build & sign Ubuntu package
|
||||||
|
|
||||||
|
create-github-release:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
needs: [prereqs, windows_artifacts, osx_publish_dmg, ubuntu_sign-artifacts]
|
||||||
|
if: |
|
||||||
|
success() ||
|
||||||
|
(needs.ubuntu_sign-artifacts.result == 'skipped' &&
|
||||||
|
needs.osx_publish_dmg.result == 'success' &&
|
||||||
|
needs.windows_artifacts.result == 'success')
|
||||||
|
steps:
|
||||||
|
- name: Download Windows portable installer
|
||||||
|
uses: actions/download-artifact@v3
|
||||||
|
with:
|
||||||
|
name: win-portable-x86_64
|
||||||
|
path: win-portable-x86_64
|
||||||
|
- name: Download Windows x86_64 installer
|
||||||
|
uses: actions/download-artifact@v3
|
||||||
|
with:
|
||||||
|
name: win-installer-x86_64
|
||||||
|
path: win-installer-x86_64
|
||||||
|
- name: Download Mac dmg
|
||||||
|
uses: actions/download-artifact@v3
|
||||||
|
with:
|
||||||
|
name: osx-dmg
|
||||||
|
path: osx-dmg
|
||||||
|
- name: Download Mac pkg
|
||||||
|
uses: actions/download-artifact@v3
|
||||||
|
with:
|
||||||
|
name: osx-signed-pkg
|
||||||
|
path: osx-pkg
|
||||||
|
- name: Download Ubuntu package (signed)
|
||||||
|
if: needs.prereqs.outputs.deb_signable == 'true'
|
||||||
|
uses: actions/download-artifact@v3
|
||||||
|
with:
|
||||||
|
name: deb-package-signed
|
||||||
|
path: deb-package
|
||||||
|
- name: Download Ubuntu package (unsigned)
|
||||||
|
if: needs.prereqs.outputs.deb_signable != 'true'
|
||||||
|
uses: actions/download-artifact@v3
|
||||||
|
with:
|
||||||
|
name: deb-package-unsigned
|
||||||
|
path: deb-package
|
||||||
|
- uses: actions/github-script@v6
|
||||||
|
with:
|
||||||
|
script: |
|
||||||
|
const fs = require('fs');
|
||||||
|
const path = require('path');
|
||||||
|
|
||||||
|
var releaseMetadata = {
|
||||||
|
owner: context.repo.owner,
|
||||||
|
repo: context.repo.repo
|
||||||
|
};
|
||||||
|
|
||||||
|
// Create the release
|
||||||
|
var tagName = "${{ needs.prereqs.outputs.tag_name }}";
|
||||||
|
var createdRelease = await github.rest.repos.createRelease({
|
||||||
|
...releaseMetadata,
|
||||||
|
draft: true,
|
||||||
|
tag_name: tagName,
|
||||||
|
name: tagName
|
||||||
|
});
|
||||||
|
releaseMetadata.release_id = createdRelease.data.id;
|
||||||
|
|
||||||
|
// Uploads contents of directory to the release created above
|
||||||
|
async function uploadDirectoryToRelease(directory, includeExtensions=[]) {
|
||||||
|
return fs.promises.readdir(directory)
|
||||||
|
.then(async(files) => Promise.all(
|
||||||
|
files.filter(file => {
|
||||||
|
return includeExtensions.length==0 || includeExtensions.includes(path.extname(file).toLowerCase());
|
||||||
|
})
|
||||||
|
.map(async (file) => {
|
||||||
|
var filePath = path.join(directory, file);
|
||||||
|
github.rest.repos.uploadReleaseAsset({
|
||||||
|
...releaseMetadata,
|
||||||
|
name: file,
|
||||||
|
headers: {
|
||||||
|
"content-length": (await fs.promises.stat(filePath)).size
|
||||||
|
},
|
||||||
|
data: fs.createReadStream(filePath)
|
||||||
|
});
|
||||||
|
}))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
await Promise.all([
|
||||||
|
// Upload Windows artifacts
|
||||||
|
uploadDirectoryToRelease('win-installer-x86_64', ['.exe']),
|
||||||
|
uploadDirectoryToRelease('win-portable-x86_64', ['.exe']),
|
||||||
|
|
||||||
|
// Upload Mac artifacts
|
||||||
|
uploadDirectoryToRelease('osx-dmg'),
|
||||||
|
uploadDirectoryToRelease('osx-pkg'),
|
||||||
|
|
||||||
|
// Upload Ubuntu artifacts
|
||||||
|
uploadDirectoryToRelease('deb-package')
|
||||||
|
]);
|
Загрузка…
Ссылка в новой задаче