|  | 
|  | 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