diff --git a/.github/workflows/continuous-integration.yml b/.github/workflows/continuous-integration.yml index 610574f80..b0ffeb2d8 100644 --- a/.github/workflows/continuous-integration.yml +++ b/.github/workflows/continuous-integration.yml @@ -54,6 +54,9 @@ jobs: linux: name: Linux runs-on: ubuntu-latest + strategy: + matrix: + runtime: [ linux-x64, linux-arm64, linux-arm ] steps: - uses: actions/checkout@v4 @@ -67,7 +70,10 @@ jobs: run: dotnet restore - name: Build - run: dotnet build --configuration LinuxRelease + run: | + dotnet build src/linux/Packaging.Linux/*.csproj \ + --configuration=Release --no-self-contained \ + --runtime=${{ matrix.runtime }} - name: Test run: | @@ -82,7 +88,7 @@ jobs: - name: Upload artifacts uses: actions/upload-artifact@v4 with: - name: linux-x64 + name: ${{ matrix.runtime }} path: | artifacts diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 3a2e708ca..1e020c425 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -232,6 +232,9 @@ jobs: runs-on: ubuntu-latest environment: release needs: prereqs + strategy: + matrix: + runtime: [ linux-x64, linux-arm64, linux-arm ] steps: - uses: actions/checkout@v4 @@ -241,7 +244,10 @@ jobs: dotnet-version: 8.0.x - name: Build - run: dotnet build --configuration=LinuxRelease + run: | + dotnet build src/linux/Packaging.Linux/*.csproj \ + --configuration=LinuxRelease --no-self-contained \ + --runtime=${{ matrix.runtime }} - name: Run Linux unit tests run: | @@ -286,18 +292,18 @@ jobs: run: | # Sign Debian package version=${{ needs.prereqs.outputs.version }} - mv out/linux/Packaging.Linux/Release/deb/gcm-linux_amd64.$version.deb . - debsigs --sign=origin --verify --check gcm-linux_amd64.$version.deb + mv out/linux/Packaging.Linux/Release/deb/gcm-${{ matrix.runtime }}.$version.deb . + debsigs --sign=origin --verify --check gcm-${{ matrix.runtime }}.$version.deb # Generate tarball signature file mv -v out/linux/Packaging.Linux/Release/tar/* . - gpg --batch --yes --armor --output gcm-linux_amd64.$version.tar.gz.asc \ - --detach-sig gcm-linux_amd64.$version.tar.gz + gpg --batch --yes --armor --output gcm-${{ matrix.runtime }}.$version.tar.gz.asc \ + --detach-sig gcm-${{ matrix.runtime }}.$version.tar.gz - name: Upload artifacts uses: actions/upload-artifact@v4 with: - name: linux-artifacts + name: ${{ matrix.runtime }}-artifacts path: | ./*.deb ./*.asc @@ -466,9 +472,9 @@ jobs: matrix: component: - os: ubuntu-latest - artifact: linux-artifacts + artifact: linux-x64-artifacts command: git-credential-manager - description: linux + description: linux-x64 - os: macos-latest artifact: macos-osx-x64-artifacts command: git-credential-manager @@ -510,15 +516,15 @@ jobs: Start-Process -Wait -FilePath "$exePath" -ArgumentList "/SILENT /VERYSILENT /NORESTART" } - - name: Install Linux (Debian package) - if: contains(matrix.component.description, 'linux') + - name: Install Linux x64 (Debian package) + if: contains(matrix.component.description, 'linux-x64') run: | debpath=$(find ./*.deb) sudo apt install $debpath "${{ matrix.component.command }}" configure - - name: Install Linux (tarball) - if: contains(matrix.component.description, 'linux') + - name: Install Linux x64 (tarball) + if: contains(matrix.component.description, 'linux-x64') run: | # Ensure we find only the source tarball, not the symbols tarpath=$(find . -name '*[[:digit:]].tar.gz') @@ -598,7 +604,9 @@ jobs: az keyvault secret show --name "$GPG_PUBLIC_KEY_SECRET_NAME" \ --vault-name "$AZURE_VAULT" --query "value" \ | sed -e 's/^"//' -e 's/"$//' | base64 -d >gcm-public.asc - mv gcm-public.asc linux-artifacts + cp gcm-public.asc linux-x64-artifacts/ + cp gcm-public.asc linux-arm64-artifacts/ + mv gcm-public.asc linux-arm-artifacts - uses: actions/github-script@v7 with: @@ -655,7 +663,9 @@ jobs: uploadDirectoryToRelease('osx-payload-and-symbols'), // Upload Linux artifacts - uploadDirectoryToRelease('linux-artifacts'), + uploadDirectoryToRelease('linux-x64-artifacts'), + uploadDirectoryToRelease('linux-arm64-artifacts'), + uploadDirectoryToRelease('linux-arm-artifacts'), // Upload .NET tool package uploadDirectoryToRelease('dotnet-tool-sign'), diff --git a/README.md b/README.md index 18c9b1309..6c6aa1535 100644 --- a/README.md +++ b/README.md @@ -47,8 +47,8 @@ Basic HTTP authentication support|✓|✓|✓ Proxy support|✓|✓|✓ `amd64` support|✓|✓|✓ `x86` support|✓|_N/A_|✗ -`arm64` support|best effort|✓|best effort, no packages -`armhf` support|_N/A_|_N/A_|best effort, no packages +`arm64` support|best effort|✓|✓ +`armhf` support|_N/A_|_N/A_|✓ (\*) GCM guarantees support only for [the Linux distributions that are officially supported by dotnet][dotnet-distributions]. diff --git a/docs/development.md b/docs/development.md index 7729556f9..0242d68b8 100644 --- a/docs/development.md +++ b/docs/development.md @@ -54,6 +54,12 @@ To build from the command line, run: dotnet build -c LinuxDebug ``` +If you want to build for a specific architecture, you can provide `linux-x64` or `linux-arm64` or `linux-arm` as the runtime: + +```shell +dotnet build -c LinuxDebug -r linux-arm64 +``` + You can find a copy of the Debian package (.deb) file in `out/linux/Packaging.Linux/deb/Debug`. The flat binaries can also be found in `out/linux/Packaging.Linux/payload/Debug`. diff --git a/src/linux/Packaging.Linux/Packaging.Linux.csproj b/src/linux/Packaging.Linux/Packaging.Linux.csproj index 8b9755c78..ddfb31500 100644 --- a/src/linux/Packaging.Linux/Packaging.Linux.csproj +++ b/src/linux/Packaging.Linux/Packaging.Linux.csproj @@ -24,8 +24,8 @@ - - + + diff --git a/src/linux/Packaging.Linux/build.sh b/src/linux/Packaging.Linux/build.sh index 9db7ad5e3..88f1b0359 100755 --- a/src/linux/Packaging.Linux/build.sh +++ b/src/linux/Packaging.Linux/build.sh @@ -30,6 +30,10 @@ case "$i" in INSTALL_FROM_SOURCE="${i#*=}" shift # past argument=value ;; + --runtime=*) + RUNTIME="${i#*=}" + shift # past argument=value + ;; --install-prefix=*) INSTALL_PREFIX="${i#*=}" shift # past argument=value @@ -45,6 +49,28 @@ if [ ! -d "$INSTALL_PREFIX" ]; then mkdir -p "$INSTALL_PREFIX" fi +# Fall back to host architecture if no explicit runtime is given. +if test -z "$RUNTIME"; then + HOST_ARCH="`dpkg-architecture -q DEB_HOST_ARCH`" + + case $HOST_ARCH in + amd64) + RUNTIME="linux-x64" + ;; + arm64) + RUNTIME="linux-arm64" + ;; + armhf) + RUNTIME="linux-arm" + ;; + *) + die "Could not determine host architecture!" + ;; + esac +fi + +echo "Building for runtime ${RUNTIME}" + # Perform pre-execution checks CONFIGURATION="${CONFIGURATION:=Debug}" if [ -z "$VERSION" ]; then @@ -56,7 +82,7 @@ PAYLOAD="$OUTDIR/payload" SYMBOLS="$OUTDIR/payload.sym" # Lay out payload -"$INSTALLER_SRC/layout.sh" --configuration="$CONFIGURATION" || exit 1 +"$INSTALLER_SRC/layout.sh" --configuration="$CONFIGURATION" --runtime="$RUNTIME" || exit 1 if [ $INSTALL_FROM_SOURCE = true ]; then echo "Installing to $INSTALL_PREFIX" @@ -79,7 +105,7 @@ if [ $INSTALL_FROM_SOURCE = true ]; then echo "Install complete." else # Pack - "$INSTALLER_SRC/pack.sh" --configuration="$CONFIGURATION" --payload="$PAYLOAD" --symbols="$SYMBOLS" --version="$VERSION" || exit 1 + "$INSTALLER_SRC/pack.sh" --configuration="$CONFIGURATION" --runtime="$RUNTIME" --payload="$PAYLOAD" --symbols="$SYMBOLS" --version="$VERSION" || exit 1 fi echo "Build of Packaging.Linux complete." diff --git a/src/linux/Packaging.Linux/layout.sh b/src/linux/Packaging.Linux/layout.sh index 6679c39ca..9355eaa02 100755 --- a/src/linux/Packaging.Linux/layout.sh +++ b/src/linux/Packaging.Linux/layout.sh @@ -23,6 +23,10 @@ case "$i" in CONFIGURATION="${i#*=}" shift # past argument=value ;; + --runtime=*) + RUNTIME="${i#*=}" + shift # past argument=value + ;; *) # unknown option ;; @@ -39,7 +43,10 @@ PROJ_OUT="$OUT/linux/Packaging.Linux" # Build parameters FRAMEWORK=net8.0 -RUNTIME=linux-x64 + +if [ -z "$RUNTIME" ]; then + die "--runtime was not set" +fi # Perform pre-execution checks CONFIGURATION="${CONFIGURATION:=Debug}" diff --git a/src/linux/Packaging.Linux/pack.sh b/src/linux/Packaging.Linux/pack.sh index 14d26aee5..817704f76 100755 --- a/src/linux/Packaging.Linux/pack.sh +++ b/src/linux/Packaging.Linux/pack.sh @@ -28,6 +28,10 @@ case "$i" in SYMBOLS="${i#*=}" shift # past argument=value ;; + --runtime=*) + RUNTIME="${i#*=}" + shift # past argument=value + ;; --configuration=*) CONFIGURATION="${i#*=}" shift # past argument=value @@ -51,20 +55,17 @@ fi if [ -z "$SYMBOLS" ]; then die "--symbols was not set" fi - -ARCH="`dpkg-architecture -q DEB_HOST_ARCH`" - -if test -z "$ARCH"; then - die "Could not determine host architecture!" +if [ -z "$RUNTIME" ]; then + die "--runtime was not set" fi TAROUT="$PROJ_OUT/$CONFIGURATION/tar/" -TARBALL="$TAROUT/gcm-linux_$ARCH.$VERSION.tar.gz" -SYMTARBALL="$TAROUT/gcm-linux_$ARCH.$VERSION-symbols.tar.gz" +TARBALL="$TAROUT/gcm-$RUNTIME.$VERSION.tar.gz" +SYMTARBALL="$TAROUT/gcm-$RUNTIME.$VERSION-symbols.tar.gz" DEBOUT="$PROJ_OUT/$CONFIGURATION/deb" DEBROOT="$DEBOUT/root" -DEBPKG="$DEBOUT/gcm-linux_$ARCH.$VERSION.deb" +DEBPKG="$DEBOUT/gcm-$RUNTIME.$VERSION.deb" mkdir -p "$DEBROOT" # Set full read, write, execute permissions for owner and just read and execute permissions for group and other @@ -99,6 +100,22 @@ INSTALL_TO="$DEBROOT/usr/local/share/gcm-core/" LINK_TO="$DEBROOT/usr/local/bin/" mkdir -p "$DEBROOT/DEBIAN" "$INSTALL_TO" "$LINK_TO" || exit 1 +# Determine architecture for debian control file from the runtime architecture +case $RUNTIME in + linux-x64) + ARCH="amd64" + ;; + linux-arm64) + ARCH="arm64" + ;; + linux-arm) + ARCH="armhf" + ;; + *) + die "Incompatible runtime architecture given for pack.sh" + ;; +esac + # make the debian control file # this is purposefully not indented, see # https://stackoverflow.com/questions/9349616/bash-eof-in-if-statement diff --git a/src/shared/Git-Credential-Manager/Git-Credential-Manager.csproj b/src/shared/Git-Credential-Manager/Git-Credential-Manager.csproj index 2b594e3eb..456adf547 100644 --- a/src/shared/Git-Credential-Manager/Git-Credential-Manager.csproj +++ b/src/shared/Git-Credential-Manager/Git-Credential-Manager.csproj @@ -4,7 +4,7 @@ Exe net8.0 net472;net8.0 - win-x86;osx-x64;linux-x64;osx-arm64 + win-x86;osx-x64;linux-x64;osx-arm64;linux-arm64;linux-arm x86 git-credential-manager GitCredentialManager