Skip to content

Commit bcfec90

Browse files
vdyedscho
authored andcommitted
release: create initial Windows installer build workflow
- trigger on tag matching basic "vfs" version pattern - validate tag is annotated & matches stricter checks - include `scalar` - build x86_64 & portable git installers, upload artifacts to workflow Update Apr 18, 2022: these steps are built explicitly on 'windows-2019' agents (rather than 'windows-latest') to ensure the correct version of Visual Studio is used (verified in the pipeline via 'type -p mspdb140.dll'). Additionally, due to a known (but not-yet-fixed) issue downloading the 'build-installers' flavor of the Git for Windows SDK with the 'git-for-windows/setup-git-for-windows-sdk' Action, the SDK used is the 'full' flavor. Signed-off-by: Victoria Dye <[email protected]> Signed-off-by: Johannes Schindelin <[email protected]>
1 parent 3184b3d commit bcfec90

File tree

1 file changed

+317
-0
lines changed

1 file changed

+317
-0
lines changed
Lines changed: 317 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,317 @@
1+
name: build-git-installers
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+
outputs:
13+
tag_name: ${{ steps.tag.outputs.name }} # The full name of the tag, e.g. v2.32.0.vfs.0.0
14+
tag_version: ${{ steps.tag.outputs.version }} # The version number (without preceding "v"), e.g. 2.32.0.vfs.0.0
15+
steps:
16+
- name: Validate tag
17+
run: |
18+
echo "$GITHUB_REF" |
19+
grep -E '^refs/tags/v2\.(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)(-rc[0-9]+)?\.vfs\.0\.(0|[1-9][0-9]*)$' || {
20+
echo "::error::${GITHUB_REF#refs/tags/} is not of the form v2.<X>.<Y>[-rc<N>].vfs.0.<W>" >&2
21+
exit 1
22+
}
23+
- name: Determine tag to build
24+
run: |
25+
echo "name=${GITHUB_REF#refs/tags/}" >>$GITHUB_OUTPUT
26+
echo "version=${GITHUB_REF#refs/tags/v}" >>$GITHUB_OUTPUT
27+
id: tag
28+
- name: Clone git
29+
uses: actions/checkout@v4
30+
- name: Validate the tag identified with trigger
31+
run: |
32+
die () {
33+
echo "::error::$*" >&2
34+
exit 1
35+
}
36+
37+
# `actions/checkout` only downloads the peeled tag (i.e. the commit)
38+
git fetch origin +$GITHUB_REF:$GITHUB_REF
39+
40+
# Verify that the tag is annotated
41+
test $(git cat-file -t "$GITHUB_REF") == "tag" || die "Tag ${{ steps.tag.outputs.name }} is not annotated"
42+
43+
# Verify tag follows rules in GIT-VERSION-GEN (i.e., matches the specified "DEF_VER" in
44+
# GIT-VERSION-FILE) and matches tag determined from trigger
45+
make GIT-VERSION-FILE
46+
expected_version="${{ steps.tag.outputs.version }}"
47+
# Convert -rc to .rc to match GIT-VERSION-FILE format
48+
expected_version="${expected_version//-rc/.rc}"
49+
test "$expected_version" == "$(sed -n 's/^GIT_VERSION *= *//p'< GIT-VERSION-FILE)" || die "GIT-VERSION-FILE tag ($(cat GIT-VERSION-FILE)) does not match ${{ steps.tag.outputs.name }}"
50+
# End check prerequisites for the workflow
51+
52+
# Build Windows installers (x86_64 & aarch64; installer & portable)
53+
windows_pkg:
54+
environment: release
55+
needs: prereqs
56+
strategy:
57+
fail-fast: false
58+
matrix:
59+
arch:
60+
- name: x86_64
61+
artifact: pkg-x86_64
62+
toolchain: x86_64
63+
mingwprefix: mingw64
64+
runner: windows-2022
65+
- name: aarch64
66+
artifact: pkg-aarch64
67+
toolchain: clang-aarch64
68+
mingwprefix: clangarm64
69+
runner: windows-11-arm
70+
runs-on: ${{ matrix.arch.runner }}
71+
env:
72+
GPG_OPTIONS: "--batch --yes --no-tty --list-options no-show-photos --verify-options no-show-photos --pinentry-mode loopback"
73+
HOME: "${{github.workspace}}\\home"
74+
USERPROFILE: "${{github.workspace}}\\home"
75+
steps:
76+
- name: Configure user
77+
shell: bash
78+
run:
79+
USER_NAME="${{github.actor}}" &&
80+
USER_EMAIL="${{github.actor}}@users.noreply.github.com" &&
81+
mkdir -p "$HOME" &&
82+
git config --global user.name "$USER_NAME" &&
83+
git config --global user.email "$USER_EMAIL" &&
84+
echo "PACKAGER=$USER_NAME <$USER_EMAIL>" >>$GITHUB_ENV
85+
- uses: git-for-windows/setup-git-for-windows-sdk@v1
86+
with:
87+
flavor: build-installers
88+
architecture: ${{ matrix.arch.name }}
89+
- name: Clone build-extra
90+
shell: bash
91+
run: |
92+
git clone --filter=blob:none --single-branch -b main https://github.com/git-for-windows/build-extra /usr/src/build-extra
93+
- name: Clone git
94+
shell: bash
95+
run: |
96+
# Since we cannot directly clone a specified tag (as we would a branch with `git clone -b <branch name>`),
97+
# this clone has to be done manually (via init->fetch->reset).
98+
99+
tag_name="${{ needs.prereqs.outputs.tag_name }}" &&
100+
git -c init.defaultBranch=main init &&
101+
git remote add -f origin https://github.com/git-for-windows/git &&
102+
git fetch "https://github.com/${{github.repository}}" refs/tags/${tag_name}:refs/tags/${tag_name} &&
103+
git reset --hard ${tag_name}
104+
- name: Prepare home directory for code-signing
105+
env:
106+
CODESIGN_P12: ${{secrets.CODESIGN_P12}}
107+
CODESIGN_PASS: ${{secrets.CODESIGN_PASS}}
108+
if: env.CODESIGN_P12 != '' && env.CODESIGN_PASS != ''
109+
shell: bash
110+
run: |
111+
cd home &&
112+
mkdir -p .sig &&
113+
echo -n "$CODESIGN_P12" | tr % '\n' | base64 -d >.sig/codesign.p12 &&
114+
echo -n "$CODESIGN_PASS" >.sig/codesign.pass
115+
git config --global alias.signtool '!sh "/usr/src/build-extra/signtool.sh"'
116+
- name: Prepare home directory for GPG signing
117+
if: env.GPGKEY != ''
118+
shell: bash
119+
run: |
120+
# This section ensures that the identity for the GPG key matches the git user identity, otherwise
121+
# signing will fail
122+
123+
echo '${{secrets.PRIVGPGKEY}}' | tr % '\n' | gpg $GPG_OPTIONS --import &&
124+
info="$(gpg --list-keys --with-colons "${GPGKEY%% *}" | cut -d : -f 1,10 | sed -n '/^uid/{s|uid:||p;q}')" &&
125+
git config --global user.name "${info% <*}" &&
126+
git config --global user.email "<${info#*<}"
127+
env:
128+
GPGKEY: ${{secrets.GPGKEY}}
129+
- name: Build mingw-w64-${{matrix.arch.toolchain}}-git
130+
env:
131+
GPGKEY: "${{secrets.GPGKEY}}"
132+
shell: bash
133+
run: |
134+
set -x
135+
136+
# Make sure that there is a `/usr/bin/git` that can be used by `makepkg-mingw`
137+
printf '#!/bin/sh\n\nexec /${{matrix.arch.mingwprefix}}/bin/git.exe "$@"\n' >/usr/bin/git &&
138+
139+
sh -x /usr/src/build-extra/please.sh build-mingw-w64-git --only-${{matrix.arch.name}} --build-src-pkg -o artifacts HEAD &&
140+
if test -n "$GPGKEY"
141+
then
142+
for tar in artifacts/*.tar*
143+
do
144+
/usr/src/build-extra/gnupg-with-gpgkey.sh --detach-sign --no-armor $tar
145+
done
146+
fi &&
147+
148+
b=$PWD/artifacts &&
149+
version=${{ needs.prereqs.outputs.tag_name }} &&
150+
(cd /usr/src/MINGW-packages/mingw-w64-git &&
151+
cp PKGBUILD.$version PKGBUILD &&
152+
git commit -s -m "mingw-w64-git: new version ($version)" PKGBUILD &&
153+
git bundle create "$b"/MINGW-packages.bundle origin/main..main)
154+
- name: Publish mingw-w64-${{matrix.arch.toolchain}}-git
155+
uses: actions/upload-artifact@v4
156+
with:
157+
name: "${{ matrix.arch.artifact }}"
158+
path: artifacts
159+
windows_artifacts:
160+
environment: release
161+
needs: [prereqs, windows_pkg]
162+
env:
163+
HOME: "${{github.workspace}}\\home"
164+
strategy:
165+
fail-fast: false
166+
matrix:
167+
arch:
168+
- name: x86_64
169+
artifact: pkg-x86_64
170+
toolchain: x86_64
171+
mingwprefix: mingw64
172+
runner: windows-2022
173+
- name: aarch64
174+
artifact: pkg-aarch64
175+
toolchain: clang-aarch64
176+
mingwprefix: clangarm64
177+
runner: windows-11-arm
178+
type:
179+
- name: installer
180+
fileprefix: Git
181+
- name: portable
182+
fileprefix: PortableGit
183+
runs-on: ${{ matrix.arch.runner }}
184+
steps:
185+
- name: Download ${{ matrix.arch.artifact }}
186+
uses: actions/download-artifact@v4
187+
with:
188+
name: ${{ matrix.arch.artifact }}
189+
path: ${{ matrix.arch.artifact }}
190+
- uses: git-for-windows/setup-git-for-windows-sdk@v1
191+
with:
192+
flavor: build-installers
193+
architecture: ${{ matrix.arch.name }}
194+
- name: Clone build-extra
195+
shell: bash
196+
run: |
197+
git clone --filter=blob:none --single-branch -b main https://github.com/git-for-windows/build-extra /usr/src/build-extra
198+
- name: Prepare home directory for code-signing
199+
env:
200+
CODESIGN_P12: ${{secrets.CODESIGN_P12}}
201+
CODESIGN_PASS: ${{secrets.CODESIGN_PASS}}
202+
if: env.CODESIGN_P12 != '' && env.CODESIGN_PASS != ''
203+
shell: bash
204+
run: |
205+
mkdir -p home/.sig &&
206+
echo -n "$CODESIGN_P12" | tr % '\n' | base64 -d >home/.sig/codesign.p12 &&
207+
echo -n "$CODESIGN_PASS" >home/.sig/codesign.pass &&
208+
git config --global alias.signtool '!sh "/usr/src/build-extra/signtool.sh"'
209+
- name: Retarget auto-update to microsoft/git
210+
shell: bash
211+
run: |
212+
set -x
213+
214+
b=/usr/src/build-extra &&
215+
216+
filename=$b/git-update-git-for-windows.config
217+
tr % '\t' >$filename <<-\EOF &&
218+
[update]
219+
%fromFork = microsoft/git
220+
EOF
221+
222+
sed -i -e '/^#include "file-list.iss"/a\
223+
Source: {#SourcePath}\\..\\git-update-git-for-windows.config; DestDir: {app}\\${{matrix.arch.mingwprefix}}\\bin; Flags: replacesameversion; AfterInstall: DeleteFromVirtualStore' \
224+
-e '/^Type: dirifempty; Name: {app}\\{#MINGW_BITNESS}$/i\
225+
Type: files; Name: {app}\\{#MINGW_BITNESS}\\bin\\git-update-git-for-windows.config\
226+
Type: dirifempty; Name: {app}\\{#MINGW_BITNESS}\\bin' \
227+
$b/installer/install.iss
228+
- name: Set the installer Publisher to the Git Client team
229+
shell: bash
230+
run: |
231+
b=/usr/src/build-extra &&
232+
sed -i -e 's/^\(AppPublisher=\).*/\1The Git Client Team at Microsoft/' $b/installer/install.iss
233+
- name: Let the installer configure Visual Studio to use the installed Git
234+
shell: bash
235+
run: |
236+
set -x
237+
238+
b=/usr/src/build-extra &&
239+
240+
sed -i -e '/^ *InstallAutoUpdater();$/a\
241+
CustomPostInstall();' \
242+
-e '/^ *UninstallAutoUpdater();$/a\
243+
CustomPostUninstall();' \
244+
$b/installer/install.iss &&
245+
246+
cat >>$b/installer/helpers.inc.iss <<\EOF
247+
248+
procedure CustomPostInstall();
249+
begin
250+
if not RegWriteStringValue(HKEY_CURRENT_USER,'Software\Microsoft\VSCommon\15.0\TeamFoundation\GitSourceControl','GitPath',ExpandConstant('{app}')) or
251+
not RegWriteStringValue(HKEY_CURRENT_USER,'Software\Microsoft\VSCommon\16.0\TeamFoundation\GitSourceControl','GitPath',ExpandConstant('{app}')) or
252+
not RegWriteStringValue(HKEY_CURRENT_USER,'Software\Microsoft\VSCommon\17.0\TeamFoundation\GitSourceControl','GitPath',ExpandConstant('{app}')) or
253+
not RegWriteStringValue(HKEY_CURRENT_USER,'Software\Microsoft\VSCommon\18.0\TeamFoundation\GitSourceControl','GitPath',ExpandConstant('{app}')) or
254+
not RegWriteStringValue(HKEY_CURRENT_USER,'Software\Microsoft\VSCommon\19.0\TeamFoundation\GitSourceControl','GitPath',ExpandConstant('{app}')) or
255+
not RegWriteStringValue(HKEY_CURRENT_USER,'Software\Microsoft\VSCommon\20.0\TeamFoundation\GitSourceControl','GitPath',ExpandConstant('{app}')) then
256+
LogError('Could not register TeamFoundation\GitSourceControl');
257+
end;
258+
259+
procedure CustomPostUninstall();
260+
begin
261+
if not RegDeleteValue(HKEY_CURRENT_USER,'Software\Microsoft\VSCommon\15.0\TeamFoundation\GitSourceControl','GitPath') or
262+
not RegDeleteValue(HKEY_CURRENT_USER,'Software\Microsoft\VSCommon\16.0\TeamFoundation\GitSourceControl','GitPath') or
263+
not RegDeleteValue(HKEY_CURRENT_USER,'Software\Microsoft\VSCommon\17.0\TeamFoundation\GitSourceControl','GitPath') or
264+
not RegDeleteValue(HKEY_CURRENT_USER,'Software\Microsoft\VSCommon\18.0\TeamFoundation\GitSourceControl','GitPath') or
265+
not RegDeleteValue(HKEY_CURRENT_USER,'Software\Microsoft\VSCommon\19.0\TeamFoundation\GitSourceControl','GitPath') or
266+
not RegDeleteValue(HKEY_CURRENT_USER,'Software\Microsoft\VSCommon\20.0\TeamFoundation\GitSourceControl','GitPath') then
267+
LogError('Could not register TeamFoundation\GitSourceControl');
268+
end;
269+
EOF
270+
- name: Enable Scalar/C and the auto-updater in the installer by default
271+
shell: bash
272+
run: |
273+
set -x
274+
275+
b=/usr/src/build-extra &&
276+
277+
sed -i -e "/ChosenOptions:=''/a\\
278+
if (ExpandConstant('{param:components|/}')='/') then begin\n\
279+
WizardSelectComponents('autoupdate');\n\
280+
#ifdef WITH_SCALAR\n\
281+
WizardSelectComponents('scalar');\n\
282+
#endif\n\
283+
end;" $b/installer/install.iss
284+
- name: Build ${{matrix.type.name}} (${{matrix.arch.name}})
285+
shell: bash
286+
run: |
287+
set -x
288+
289+
# Copy the PDB archive to the directory where `--include-pdbs` expects it
290+
b=/usr/src/build-extra &&
291+
mkdir -p $b/cached-source-packages &&
292+
cp ${{matrix.arch.artifact}}/*-pdb* $b/cached-source-packages/ &&
293+
294+
# Build the installer, embedding PDBs
295+
eval $b/please.sh make_installers_from_mingw_w64_git --include-pdbs \
296+
--version=${{ needs.prereqs.outputs.tag_version }} \
297+
-o artifacts --${{matrix.type.name}} \
298+
--pkg=${{matrix.arch.artifact}}/mingw-w64-${{matrix.arch.toolchain}}-git-[0-9]*.tar.xz \
299+
--pkg=${{matrix.arch.artifact}}/mingw-w64-${{matrix.arch.toolchain}}-git-doc-html-[0-9]*.tar.xz &&
300+
301+
if test portable = '${{matrix.type.name}}' && test -n "$(git config alias.signtool)"
302+
then
303+
git signtool artifacts/PortableGit-*.exe
304+
fi &&
305+
openssl dgst -sha256 artifacts/${{matrix.type.fileprefix}}-*.exe | sed "s/.* //" >artifacts/sha-256.txt
306+
- name: Verify that .exe files are code-signed
307+
if: env.CODESIGN_P12 != '' && env.CODESIGN_PASS != ''
308+
shell: bash
309+
run: |
310+
PATH=$PATH:"/c/Program Files (x86)/Windows Kits/10/App Certification Kit/" \
311+
signtool verify //pa artifacts/${{matrix.type.fileprefix}}-*.exe
312+
- name: Publish ${{matrix.type.name}}-${{matrix.arch.name}}
313+
uses: actions/upload-artifact@v4
314+
with:
315+
name: win-${{matrix.type.name}}-${{matrix.arch.name}}
316+
path: artifacts
317+
# End build Windows installers

0 commit comments

Comments
 (0)