build-git-installers #226
Workflow file for this run
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
name: build-git-installers | |
on: | |
push: | |
tags: | |
- 'v[0-9]*vfs*' # matches "v<number><any characters>vfs<any characters>" | |
permissions: | |
id-token: write # required for Azure login via OIDC | |
jobs: | |
test: | |
runs-on: ubuntu-latest | |
container: | |
image: ubuntu:16.04 # expanded security maintenance until 04/02/2026, according to https://endoflife.date/ubuntu | |
volumes: | |
# override /__e/node20 because GitHub Actions uses a version that requires too-recent glibc | |
- /tmp:/__e/node20 | |
steps: | |
- name: Install git dependencies | |
run: | | |
set -ex | |
apt-get update -q | |
apt-get install -y -q --no-install-recommends gettext libcurl4-gnutls-dev libpcre3-dev asciidoc xmlto curl ca-certificates | |
NODE_VERSION=v20.18.1 && | |
NODE_URL=https://unofficial-builds.nodejs.org/download/release/$NODE_VERSION/node-$NODE_VERSION-linux-x64-musl.tar.gz && | |
curl -Lo /tmp/node.tar.gz $NODE_URL && | |
tar -C /__e/node20 -x --strip-components=1 -f /tmp/node.tar.gz && | |
ls -la /__e/node20/bin && | |
{ ldd /__e/node20/bin/node || :; } && | |
/__e/node20/bin/node --version | |
- name: Clone git | |
uses: actions/checkout@v4 | |
with: | |
path: git | |
# Check prerequisites for the workflow | |
prereqs: | |
runs-on: ubuntu-latest | |
needs: test | |
environment: release | |
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 | |
steps: | |
- name: Determine tag to build | |
run: | | |
exit 1 | |
echo "name=${GITHUB_REF#refs/tags/}" >>$GITHUB_OUTPUT | |
echo "version=${GITHUB_REF#refs/tags/v}" >>$GITHUB_OUTPUT | |
id: tag | |
# End check prerequisites for the workflow | |
# Build and sign Debian package | |
create-linux-artifacts: | |
runs-on: ubuntu-latest | |
container: | |
image: ubuntu:16.04 # expanded security maintenance until 04/02/2026, according to https://endoflife.date/ubuntu | |
volumes: | |
# override /__e/node20 because GitHub Actions uses a version that requires too-recent glibc | |
- /tmp:/__e/node20 | |
needs: prereqs | |
environment: release | |
steps: | |
- name: Install git dependencies | |
run: | | |
set -ex | |
apt-get update -q | |
apt-get install -y -q --no-install-recommends gettext libcurl4-gnutls-dev libpcre3-dev asciidoc xmlto curl | |
NODE_VERSION=v20.18.1 && | |
NODE_URL=https://unofficial-builds.nodejs.org/download/release/$NODE_VERSION/node-$NODE_VERSION-linux-x64-musl.tar.gz && | |
curl -Lo /tmp/node.tar.gz $NODE_URL && | |
tar -C /__e/node20 -x --strip-components=1 -f /tmp/node.tar.gz | |
- name: Clone git | |
uses: actions/checkout@v4 | |
with: | |
path: git | |
- name: Build and create Debian package | |
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: GitClient <[email protected]> | |
Description: Git client built from the https://github.com/microsoft/git repository, | |
specialized in supporting monorepo scenarios. Includes the Scalar CLI. | |
EOF | |
dpkg-deb -Zxz --build "$PKGNAME" | |
# Move Debian package for later artifact upload | |
mv "$PKGNAME.deb" "$GITHUB_WORKSPACE" | |
- name: Log into Azure | |
uses: azure/login@v2 | |
with: | |
client-id: ${{ secrets.AZURE_CLIENT_ID }} | |
tenant-id: ${{ secrets.AZURE_TENANT_ID }} | |
subscription-id: ${{ secrets.AZURE_SUBSCRIPTION_ID }} | |
- name: Prepare for GPG signing | |
env: | |
AZURE_VAULT: ${{ secrets.AZURE_VAULT }} | |
GPG_KEY_SECRET_NAME: ${{ secrets.GPG_KEY_SECRET_NAME }} | |
GPG_PASSPHRASE_SECRET_NAME: ${{ secrets.GPG_PASSPHRASE_SECRET_NAME }} | |
GPG_KEYGRIP_SECRET_NAME: ${{ secrets.GPG_KEYGRIP_SECRET_NAME }} | |
run: | | |
# Install debsigs | |
apt install debsigs | |
# Download GPG key, passphrase, and keygrip from Azure Key Vault | |
key=$(az keyvault secret show --name $GPG_KEY_SECRET_NAME --vault-name $AZURE_VAULT --query "value") | |
passphrase=$(az keyvault secret show --name $GPG_PASSPHRASE_SECRET_NAME --vault-name $AZURE_VAULT --query "value") | |
keygrip=$(az keyvault secret show --name $GPG_KEYGRIP_SECRET_NAME --vault-name $AZURE_VAULT --query "value") | |
# Remove quotes from downloaded values | |
key=$(sed -e 's/^"//' -e 's/"$//' <<<"$key") | |
passphrase=$(sed -e 's/^"//' -e 's/"$//' <<<"$passphrase") | |
keygrip=$(sed -e 's/^"//' -e 's/"$//' <<<"$keygrip") | |
# Import GPG key | |
echo "$key" | base64 -d | gpg --import --no-tty --batch --yes | |
# Configure GPG | |
echo "allow-preset-passphrase" > ~/.gnupg/gpg-agent.conf | |
gpg-connect-agent RELOADAGENT /bye | |
/usr/lib/gnupg2/gpg-preset-passphrase --preset "$keygrip" <<<"$passphrase" | |
- name: Sign Debian package | |
run: | | |
# Sign Debian package | |
version="${{ needs.prereqs.outputs.tag_version }}" | |
debsigs --sign=origin --verify --check microsoft-git_"$version".deb | |
- name: Upload artifacts | |
uses: actions/upload-artifact@v4 | |
with: | |
name: linux-artifacts | |
path: | | |
*.deb | |
# End build and sign Debian package | |
# Validate installers | |
validate-installers: | |
name: Validate installers | |
strategy: | |
matrix: | |
component: | |
- os: ubuntu-latest | |
artifact: linux-artifacts | |
command: git | |
runs-on: ${{ matrix.component.os }} | |
needs: [prereqs, create-linux-artifacts] | |
steps: | |
- name: Download artifacts | |
uses: actions/download-artifact@v4 | |
with: | |
name: ${{ matrix.component.artifact }} | |
- name: Install Windows | |
if: contains(matrix.component.artifact, 'win-installer') | |
shell: pwsh | |
run: | | |
$exePath = Get-ChildItem -Path ./*.exe | %{$_.FullName} | |
Start-Process -Wait -FilePath "$exePath" -ArgumentList "/SILENT /VERYSILENT /NORESTART /SUPPRESSMSGBOXES /ALLOWDOWNGRADE=1" | |
- name: Install Linux | |
if: contains(matrix.component.artifact, 'linux') | |
run: | | |
debpath=$(find ./*.deb) | |
sudo apt install $debpath | |
- name: Install macOS | |
if: contains(matrix.component.artifact, 'macos') | |
run: | | |
# avoid letting Homebrew's `git` in `/opt/homebrew/bin` override `/usr/local/bin/git` | |
arch="$(uname -m)" | |
test arm64 != "$arch" || | |
brew uninstall git | |
pkgpath=$(find ./*universal*.pkg) | |
sudo installer -pkg $pkgpath -target / | |
- name: Validate | |
shell: bash | |
run: | | |
"${{ matrix.component.command }}" --version | sed 's/git version //' >actual | |
echo ${{ needs.prereqs.outputs.tag_version }} >expect | |
cmp expect actual || exit 1 | |
- name: Validate universal binary CPU architecture | |
if: contains(matrix.component.os, 'macos') | |
shell: bash | |
run: | | |
set -ex | |
git version --build-options >actual | |
cat actual | |
grep "cpu: $(uname -m)" actual | |
# End validate installers |