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