Skip to content

Commit b817109

Browse files
committed
build-git-installers: update windows signing
This commit contains two temporary workflows: 1. windows-full: This workflow was designed to use the same key used for Linux signing for GPG signing. It also uses the Azure Code Signing action to sign Windows installers. 2. windows-minimal: This workflow was intended to test the minimal requirements for Windows builds to see whether it is possible to use Azure Code Signing as the singtool alias for exe signing. This workflow is already set up with tmate for testing on GitHub Actions runners (since the issue described below does not repro locally). While we were unable to get past an issue with the second workflow hanging instead of executing signing, hopefully this will provide a solid starting point if someone would like to re-attempt Azure Code Signing/GPG signing for microsoft/git in the future. Note: If signing is successfully implemented with the alias used in workflow microsoft#2, this alias should also be used for installer signing rather than the Azure Code Signing action so that the embedded uninstaller is signed in addition to the installers.
1 parent 7a89262 commit b817109

File tree

2 files changed

+525
-0
lines changed

2 files changed

+525
-0
lines changed

.github/workflows/windows-full.yml

Lines changed: 371 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,371 @@
1+
name: windows-full
2+
3+
on:
4+
push:
5+
tags:
6+
- 'v[0-9]*vfs*' # matches "v<number><any characters>vfs<any characters>"
7+
8+
jobs:
9+
# Check prerequisites for the workflow
10+
prereqs:
11+
runs-on: ubuntu-latest
12+
environment: release
13+
outputs:
14+
tag_name: ${{ steps.tag.outputs.name }} # The full name of the tag, e.g. v2.32.0.vfs.0.0
15+
tag_version: ${{ steps.tag.outputs.version }} # The version number (without preceding "v"), e.g. 2.32.0.vfs.0.0
16+
steps:
17+
- name: Validate tag
18+
run: |
19+
echo "$GITHUB_REF" |
20+
grep '^refs/tags/v2\.\(0\|[1-9][0-9]*\)\.\(0\|[1-9][0-9]*\)\.vfs\.0\.\(0\|[1-9][0-9]*\)$' || {
21+
echo "::error::${GITHUB_REF#refs/tags/} is not of the form v2.<X>.<Y>.vfs.0.<W>" >&2
22+
exit 1
23+
}
24+
- name: Determine tag to build
25+
run: |
26+
echo "name=${GITHUB_REF#refs/tags/}" >>$GITHUB_OUTPUT
27+
echo "version=${GITHUB_REF#refs/tags/v}" >>$GITHUB_OUTPUT
28+
id: tag
29+
- name: Clone git
30+
uses: actions/checkout@v3
31+
- name: Validate the tag identified with trigger
32+
run: |
33+
die () {
34+
echo "::error::$*" >&2
35+
exit 1
36+
}
37+
38+
# `actions/checkout` only downloads the peeled tag (i.e. the commit)
39+
git fetch origin +$GITHUB_REF:$GITHUB_REF
40+
41+
# Verify that the tag is annotated
42+
test $(git cat-file -t "$GITHUB_REF") == "tag" || die "Tag ${{ steps.tag.outputs.name }} is not annotated"
43+
44+
# Verify tag follows rules in GIT-VERSION-GEN (i.e., matches the specified "DEF_VER" in
45+
# GIT-VERSION-FILE) and matches tag determined from trigger
46+
make GIT-VERSION-FILE
47+
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 }}"
48+
# End check prerequisites for the workflow
49+
50+
# Build and sign Windows installers & upload artifacts
51+
windows_pkg:
52+
runs-on: windows-2019
53+
environment: release
54+
needs: prereqs
55+
env:
56+
GPG_OPTIONS: "--batch --yes --no-tty --list-options no-show-photos --verify-options no-show-photos --pinentry-mode loopback"
57+
HOME: "${{github.workspace}}\\home"
58+
USERPROFILE: "${{github.workspace}}\\home"
59+
steps:
60+
- name: Configure user
61+
shell: bash
62+
run:
63+
USER_NAME="${{github.actor}}" &&
64+
USER_EMAIL="${{github.actor}}@users.noreply.github.com" &&
65+
mkdir -p "$HOME" &&
66+
git config --global user.name "$USER_NAME" &&
67+
git config --global user.email "$USER_EMAIL" &&
68+
echo "PACKAGER=$USER_NAME <$USER_EMAIL>" >>$GITHUB_ENV
69+
70+
- uses: git-for-windows/setup-git-for-windows-sdk@v1
71+
with:
72+
flavor: build-installers
73+
74+
- name: Clone build-extra
75+
shell: bash
76+
run: |
77+
git clone --filter=blob:none --single-branch -b main https://github.com/git-for-windows/build-extra /usr/src/build-extra
78+
79+
- name: Clone git
80+
shell: bash
81+
run: |
82+
# Since we cannot directly clone a specified tag (as we would a branch with `git clone -b <branch name>`),
83+
# this clone has to be done manually (via init->fetch->reset).
84+
85+
tag_name="${{ needs.prereqs.outputs.tag_name }}" &&
86+
git -c init.defaultBranch=main init &&
87+
git remote add -f origin https://github.com/git-for-windows/git &&
88+
git fetch "https://github.com/${{github.repository}}" refs/tags/${tag_name}:refs/tags/${tag_name} &&
89+
git reset --hard ${tag_name}
90+
91+
- name: Log into Azure
92+
uses: azure/login@v1
93+
with:
94+
creds: ${{ secrets.AZURE_CREDENTIALS }}
95+
96+
- name: Configure Azure Code Signing
97+
shell: bash
98+
run: |
99+
git config alias.signtool '!f() { printf "%s\n" "$@" >./catalog && cat ./catalog && /c/Windows/System32/WindowsPowerShell/v1.0/powershell -command "Invoke-AzureCodeSigning -Endpoint https://wus2.codesigning.azure.net/ -CodeSigningAccountName git-fundamentals-signing -CertificateProfileName git-fundamentals-windows-signing -FilesCatalog ./catalog -FileDigest SHA256 -TimestampRfc3161 http://timestamp.acs.microsoft.com -TimestampDigest SHA256"; };f'
100+
101+
- name: Prepare for GPG signing
102+
env:
103+
AZURE_VAULT: ${{ secrets.AZURE_VAULT }}
104+
GPG_KEY_SECRET_NAME: ${{ secrets.GPG_KEY_SECRET_NAME }}
105+
GPG_PASSPHRASE_SECRET_NAME: ${{ secrets.GPG_PASSPHRASE_SECRET_NAME }}
106+
GPG_KEYGRIP_SECRET_NAME: ${{ secrets.GPG_KEYGRIP_SECRET_NAME }}
107+
shell: bash
108+
run: |
109+
# Download GPG key, passphrase, and keygrip from Azure Key Vault
110+
key=$(az keyvault secret show --name $GPG_KEY_SECRET_NAME --vault-name $AZURE_VAULT --query "value")
111+
passphrase=$(az keyvault secret show --name $GPG_PASSPHRASE_SECRET_NAME --vault-name $AZURE_VAULT --query "value")
112+
keygrip=$(az keyvault secret show --name $GPG_KEYGRIP_SECRET_NAME --vault-name $AZURE_VAULT --query "value")
113+
114+
# Remove quotes from downloaded values
115+
key=$(sed -e 's/^"//' -e 's/"$//' <<<"$key")
116+
passphrase=$(sed -e 's/^"//' -e 's/"$//' <<<"$passphrase")
117+
keygrip=$(sed -e 's/^"//' -e 's/"$//' <<<"$keygrip")
118+
119+
# Import GPG key
120+
echo "$key" | base64 -d | gpg $GPG_OPTIONS --import
121+
122+
# Configure GPG
123+
echo "allow-preset-passphrase" > ~/.gnupg/gpg-agent.conf
124+
gpg-connect-agent RELOADAGENT /bye
125+
gpg-connect-agent 'PRESET_PASSPHRASE "$keygrip" -1 "$passphrase"' /bye
126+
127+
- name: Prepare home directory for GPG signing
128+
if: env.GPG_FINGERPRINT_SECRET_NAME != ''
129+
shell: bash
130+
run: |
131+
# This section ensures that the identity for the GPG key matches the git user identity, otherwise
132+
# signing will fail
133+
134+
# Get GPG key fingerprint from Azure Key Vault
135+
GPGKEY=$(az keyvault secret show --name "$GPG_FINGERPRINT_SECRET_NAME" \
136+
--vault-name "$AZURE_VAULT" --query "value" \
137+
| sed -e 's/^"//' -e 's/"$//')
138+
139+
info="$(gpg --list-keys --with-colons "${GPGKEY%% *}" | cut -d : -f 1,10 | sed -n '/^uid/{s|uid:||p;q}')" &&
140+
git config --global user.name "${info% <*}" &&
141+
git config --global user.email "<${info#*<}"
142+
env:
143+
AZURE_VAULT: ${{ secrets.AZURE_VAULT }}
144+
GPG_FINGERPRINT_SECRET_NAME: ${{secrets.GPG_FINGERPRINT_SECRET_NAME}}
145+
146+
- name: Build mingw-w64-x86_64-git
147+
env:
148+
AZURE_VAULT: ${{ secrets.AZURE_VAULT }}
149+
GPG_FINGERPRINT_SECRET_NAME: ${{secrets.GPG_FINGERPRINT_SECRET_NAME}}
150+
shell: bash
151+
run: |
152+
set -x
153+
154+
# Get GPG key fingerprint from Azure Key Vault
155+
GPGKEY=$(az keyvault secret show --name "$GPG_FINGERPRINT_SECRET_NAME" \
156+
--vault-name "$AZURE_VAULT" --query "value" \
157+
| sed -e 's/^"//' -e 's/"$//')
158+
159+
# Make sure that there is a `/usr/bin/git` that can be used by `makepkg-mingw`
160+
printf '#!/bin/sh\n\nexec /mingw64/bin/git.exe "$@"\n' >/usr/bin/git &&
161+
162+
# Restrict `PATH` to MSYS2 and to Visual Studio (to let `cv2pdb` find the relevant DLLs)
163+
PATH="/mingw64/bin:/usr/bin:/C/Program Files (x86)/Microsoft Visual Studio 14.0/VC/bin/amd64:/C/Windows/system32"
164+
165+
type -p mspdb140.dll || exit 1
166+
167+
# Install Azure Code Signing Module
168+
/c/Windows/System32/WindowsPowerShell/v1.0/powershell -command "Install-Module -Name AzureCodeSigning -RequiredVersion 0.2.24 -Force -Repository PSGallery"
169+
sh -x /usr/src/build-extra/please.sh build-mingw-w64-git --only-64-bit --build-src-pkg -o artifacts HEAD
170+
171+
- name: Sign tarballs with GPG
172+
shell: bash
173+
run: |
174+
if test -n "$GPGKEY"
175+
then
176+
for tar in artifacts/*.tar*
177+
do
178+
/usr/src/build-extra/gnupg-with-gpgkey.sh --detach-sign --no-armor $tar
179+
done
180+
fi &&
181+
182+
b=$PWD/artifacts &&
183+
version=${{ needs.prereqs.outputs.tag_name }} &&
184+
(cd /usr/src/MINGW-packages/mingw-w64-git &&
185+
cp PKGBUILD.$version PKGBUILD &&
186+
git commit -s -m "mingw-w64-git: new version ($version)" PKGBUILD &&
187+
git bundle create "$b"/MINGW-packages.bundle origin/main..main)
188+
189+
- name: Publish mingw-w64-x86_64-git
190+
uses: actions/upload-artifact@v3
191+
with:
192+
name: pkg-x86_64
193+
path: artifacts
194+
195+
create-windows-artifacts:
196+
runs-on: windows-2019
197+
environment: release
198+
needs: [prereqs, windows_pkg]
199+
env:
200+
HOME: "${{github.workspace}}\\home"
201+
strategy:
202+
matrix:
203+
artifact:
204+
- name: installer
205+
fileprefix: Git
206+
- name: portable
207+
fileprefix: PortableGit
208+
fail-fast: false
209+
steps:
210+
- name: Download pkg-x86_64
211+
uses: actions/download-artifact@v3
212+
with:
213+
name: pkg-x86_64
214+
path: pkg-x86_64
215+
216+
- uses: git-for-windows/setup-git-for-windows-sdk@v1
217+
with:
218+
flavor: build-installers
219+
220+
- name: Clone build-extra
221+
shell: bash
222+
run: |
223+
git clone --filter=blob:none --single-branch -b main https://github.com/git-for-windows/build-extra /usr/src/build-extra
224+
225+
- name: Retarget auto-update to microsoft/git
226+
shell: bash
227+
run: |
228+
set -x
229+
230+
b=/usr/src/build-extra &&
231+
232+
filename=$b/git-update-git-for-windows.config
233+
tr % '\t' >$filename <<-\EOF &&
234+
[update]
235+
%fromFork = microsoft/git
236+
EOF
237+
238+
sed -i -e '/^#include "file-list.iss"/a\
239+
Source: {#SourcePath}\\..\\git-update-git-for-windows.config; DestDir: {app}\\mingw64\\bin; Flags: replacesameversion; AfterInstall: DeleteFromVirtualStore' \
240+
-e '/^Type: dirifempty; Name: {app}\\{#MINGW_BITNESS}$/i\
241+
Type: files; Name: {app}\\{#MINGW_BITNESS}\\bin\\git-update-git-for-windows.config\
242+
Type: dirifempty; Name: {app}\\{#MINGW_BITNESS}\\bin' \
243+
$b/installer/install.iss
244+
245+
- name: Set alerts to continue until upgrade is taken
246+
shell: bash
247+
run: |
248+
set -x
249+
250+
b=/mingw64/bin &&
251+
252+
sed -i -e '6 a use_recently_seen=no' \
253+
$b/git-update-git-for-windows
254+
255+
- name: Set the installer Publisher to the Git Fundamentals team
256+
shell: bash
257+
run: |
258+
b=/usr/src/build-extra &&
259+
sed -i -e 's/^\(AppPublisher=\).*/\1The Git Fundamentals Team at GitHub/' $b/installer/install.iss
260+
261+
- name: Let the installer configure Visual Studio to use the installed Git
262+
shell: bash
263+
run: |
264+
set -x
265+
266+
b=/usr/src/build-extra &&
267+
268+
sed -i -e '/^ *InstallAutoUpdater();$/a\
269+
CustomPostInstall();' \
270+
-e '/^ *UninstallAutoUpdater();$/a\
271+
CustomPostUninstall();' \
272+
$b/installer/install.iss &&
273+
274+
cat >>$b/installer/helpers.inc.iss <<\EOF
275+
276+
procedure CustomPostInstall();
277+
begin
278+
if not RegWriteStringValue(HKEY_CURRENT_USER,'Software\Microsoft\VSCommon\15.0\TeamFoundation\GitSourceControl','GitPath',ExpandConstant('{app}')) or
279+
not RegWriteStringValue(HKEY_CURRENT_USER,'Software\Microsoft\VSCommon\16.0\TeamFoundation\GitSourceControl','GitPath',ExpandConstant('{app}')) or
280+
not RegWriteStringValue(HKEY_CURRENT_USER,'Software\Microsoft\VSCommon\17.0\TeamFoundation\GitSourceControl','GitPath',ExpandConstant('{app}')) or
281+
not RegWriteStringValue(HKEY_CURRENT_USER,'Software\Microsoft\VSCommon\18.0\TeamFoundation\GitSourceControl','GitPath',ExpandConstant('{app}')) or
282+
not RegWriteStringValue(HKEY_CURRENT_USER,'Software\Microsoft\VSCommon\19.0\TeamFoundation\GitSourceControl','GitPath',ExpandConstant('{app}')) or
283+
not RegWriteStringValue(HKEY_CURRENT_USER,'Software\Microsoft\VSCommon\20.0\TeamFoundation\GitSourceControl','GitPath',ExpandConstant('{app}')) then
284+
LogError('Could not register TeamFoundation\GitSourceControl');
285+
end;
286+
287+
procedure CustomPostUninstall();
288+
begin
289+
if not RegDeleteValue(HKEY_CURRENT_USER,'Software\Microsoft\VSCommon\15.0\TeamFoundation\GitSourceControl','GitPath') or
290+
not RegDeleteValue(HKEY_CURRENT_USER,'Software\Microsoft\VSCommon\16.0\TeamFoundation\GitSourceControl','GitPath') or
291+
not RegDeleteValue(HKEY_CURRENT_USER,'Software\Microsoft\VSCommon\17.0\TeamFoundation\GitSourceControl','GitPath') or
292+
not RegDeleteValue(HKEY_CURRENT_USER,'Software\Microsoft\VSCommon\18.0\TeamFoundation\GitSourceControl','GitPath') or
293+
not RegDeleteValue(HKEY_CURRENT_USER,'Software\Microsoft\VSCommon\19.0\TeamFoundation\GitSourceControl','GitPath') or
294+
not RegDeleteValue(HKEY_CURRENT_USER,'Software\Microsoft\VSCommon\20.0\TeamFoundation\GitSourceControl','GitPath') then
295+
LogError('Could not register TeamFoundation\GitSourceControl');
296+
end;
297+
EOF
298+
299+
- name: Enable Scalar/C and the auto-updater in the installer by default
300+
shell: bash
301+
run: |
302+
set -x
303+
304+
b=/usr/src/build-extra &&
305+
306+
sed -i -e "/ChosenOptions:=''/a\\
307+
if (ExpandConstant('{param:components|/}')='/') then begin\n\
308+
WizardSelectComponents('autoupdate');\n\
309+
#ifdef WITH_SCALAR\n\
310+
WizardSelectComponents('scalar');\n\
311+
#endif\n\
312+
end;" $b/installer/install.iss
313+
314+
- name: Build 64-bit ${{matrix.artifact.name}}
315+
shell: bash
316+
run: |
317+
set -x
318+
319+
# Copy the PDB archive to the directory where `--include-pdbs` expects it
320+
b=/usr/src/build-extra &&
321+
mkdir -p $b/cached-source-packages &&
322+
cp pkg-x86_64/*-pdb* $b/cached-source-packages/ &&
323+
324+
# Build the installer, embedding PDBs
325+
eval $b/please.sh make_installers_from_mingw_w64_git --include-pdbs \
326+
--version=${{ needs.prereqs.outputs.tag_version }} \
327+
-o artifacts --${{matrix.artifact.name}} \
328+
--pkg=pkg-x86_64/mingw-w64-x86_64-git-[0-9]*.tar.xz \
329+
--pkg=pkg-x86_64/mingw-w64-x86_64-git-doc-html-[0-9]*.tar.xz &&
330+
331+
if test portable = '${{matrix.artifact.name}}' && test -n "$(git config alias.signtool)"
332+
then
333+
git signtool artifacts/PortableGit-*.exe
334+
fi &&
335+
openssl dgst -sha256 artifacts/${{matrix.artifact.fileprefix}}-*.exe | sed "s/.* //" >artifacts/sha-256.txt
336+
337+
- name: Log into Azure
338+
uses: azure/login@v1
339+
with:
340+
creds: ${{ secrets.AZURE_CREDENTIALS }}
341+
342+
- name: Install Azure Code Signing Module
343+
shell: pwsh
344+
run: |
345+
Install-Module -Name AzureCodeSigning -RequiredVersion 0.2.24 -Force `
346+
-Repository PSGallery
347+
348+
- name: Sign installers with Azure Code Signing
349+
uses: azure/[email protected]
350+
with:
351+
endpoint: https://wus2.codesigning.azure.net/
352+
code-signing-account-name: git-fundamentals-signing
353+
certificate-profile-name: git-fundamentals-windows-signing
354+
files-folder: ${{ github.workspace }}\artifacts
355+
files-folder-filter: exe
356+
file-digest: SHA256
357+
timestamp-rfc3161: http://timestamp.acs.microsoft.com
358+
timestamp-digest: SHA256
359+
360+
- name: Verify that .exe files are code-signed
361+
shell: bash
362+
run: |
363+
PATH=$PATH:"/c/Program Files (x86)/Windows Kits/10/App Certification Kit/" \
364+
signtool verify //pa artifacts/${{matrix.artifact.fileprefix}}-*.exe
365+
366+
- name: Publish ${{matrix.artifact.name}}-x86_64
367+
uses: actions/upload-artifact@v3
368+
with:
369+
name: win-${{matrix.artifact.name}}-x86_64
370+
path: artifacts
371+
# End build Windows installers

0 commit comments

Comments
 (0)