Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add a Linux .deb installer CI workflow #164

Merged
36 changes: 36 additions & 0 deletions .github/workflows/build-installers.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
name: Build-Installers

on:
push:
branches: [ master ]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We will likely want these on release branch, too? cc: @mjcheetham

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes please 👍

pull_request:
branches: [ master ]

jobs:
linux:
name: "Linux"

runs-on: ubuntu-18.04
steps:
- uses: actions/checkout@v2
with:
fetch-depth: 0 # Indicate full history so Nerdbank.GitVersioning works.

- name: Setup .NET Core
uses: actions/setup-dotnet@v1
with:
dotnet-version: 3.1.302

- name: Install dependencies
run: dotnet restore --force

- name: Build Linux Payloads
run: dotnet build -c release src/linux/Payload.Linux/Payload.Linux.csproj

- name: Upload Installers
uses: actions/upload-artifact@v2
with:
name: Installers
path: |
out/linux/*.deb
out/linux/*.tar.gz
123 changes: 109 additions & 14 deletions src/linux/Payload.Linux/build.sh
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,21 @@ die () {
exit 1
}

echo "Building Payload.Linux..."
make_absolute () {
case "$1" in
/*)
echo "$1"
;;
*)
echo "$PWD/$1"
;;
esac
}

# Directories
THISDIR="$( cd "$(dirname "$0")" ; pwd -P )"
ROOT="$( cd "$THISDIR"/../../.. ; pwd -P )"
SRC="$ROOT/src"
OUT="$ROOT/out"
PAYLOAD_SRC="$SRC/linux/Payload.Linux"
PAYLOAD_OUT="$OUT/linux/Payload.Linux"
#####################################################################
# Building
#####################################################################
echo "Building Payload.Linux..."

# Parse script arguments
for i in "$@"
Expand All @@ -32,17 +38,106 @@ case "$i" in
esac
done

# Directories
THISDIR="$( cd "$(dirname "$0")" ; pwd -P )"
ROOT="$( cd "$THISDIR"/../../.. ; pwd -P )"
SRC="$ROOT/src"
OUT="$ROOT/out"
GCM_SRC="$SRC/shared/Git-Credential-Manager"
PAYLOAD_OUT="$OUT/linux/"

# Build parameters
FRAMEWORK=netcoreapp3.1
RUNTIME=linux-x64

# Perform pre-execution checks
CONFIGURATION="${CONFIGURATION:=Debug}"
if [ -z "$VERSION" ]; then
die "--version was not set"
fi

PAYLOAD="$PAYLOAD_OUT/tar/$CONFIGURATION/payload"
TAROUT="$PAYLOAD_OUT/tar/$CONFIGURATION/gcmcore-linux-x86_64-$VERSION.tar.gz"
ARCH="`dpkg-architecture -q DEB_HOST_ARCH`"
if test -z "$ARCH"; then
die "Could not determine host architecture!"
fi

# Outputs
PAYLOAD="$PAYLOAD_OUT/payload/$CONFIGURATION"
TAROUT="$PAYLOAD_OUT/gcmcore-linux_$ARCH.$CONFIGURATION.$VERSION.tar.gz"
DEBPKG="$PAYLOAD_OUT/gcmcore-linux/"
DEBOUT="$PAYLOAD_OUT/gcmcore-linux_$ARCH.$CONFIGURATION.$VERSION.deb"
SYMBOLOUT="$PAYLOAD.sym"

# Cleanup payload directory
if [ -d "$PAYLOAD" ]; then
echo "Cleaning existing payload directory '$PAYLOAD'..."
rm -rf "$PAYLOAD"
fi

# Ensure directories exists
mkdir -p "$PAYLOAD" "$SYMBOLOUT" "$DEBPKG"

# Publish core application executables
echo "Publishing core application..."
dotnet publish "$GCM_SRC" \
--configuration="$CONFIGURATION" \
--framework="$FRAMEWORK" \
--runtime="$RUNTIME" \
--self-contained=true \
"/p:PublishSingleFile=True" \
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've thought about making GCM Core a .NET Core "single-file" on all platforms recently actually.
Perhaps we should look at setting this in the shared/Git-Credential-Manager project file directly?

One issue however with the single-file model is that of signing. As I understand it, the single-file format is basically a self extracting archive, that extracts to some location and then forwards execution to this extracted location.

The binaries inside the archive (ELF on Linux, Mach-O on macOS, and PE on Windows) will not be themselves signed. Is this an issue? I know Gatekeeper on Mac can be unhappy to run executables, and also there's Apple Notarization. For Windows I know theres some groups inside of MSFT that require all signed binaries on their build machines too.

For Linux this is less an issue of course, since there's no equivalent to Authenticode or Apple Signing for ELF and the disjointed Linux world, AFAIK.

So perhaps what I'm saying is I've just talked myself out of changing this for all projects 😆

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

CloudBuild is moving to requiring all binaries be signed IIRC so I would expect that to eventually be an issue if using gcm core to auth in cloud build (windows). This is an excellent question I'll see if I find the answer to.

--output="$(make_absolute "$PAYLOAD")" || exit 1

# Collect symbols
echo "Collecting managed symbols..."
mv "$PAYLOAD"/*.pdb "$SYMBOLOUT" || exit 1

echo "Build complete."

#####################################################################
# PACKING
#####################################################################
echo "Packing Payload.Linux..."
# Cleanup any old archive files
if [ -e "$TAROUT" ]; then
echo "Deleteing old archive '$TAROUT'..."
rm "$TAROUT"
fi

# Ensure the parent directory for the archive exists
mkdir -p "$(dirname "$TAROUT")"

# Set full read, write, execute permissions for owner and just read and execute permissions for group and other
echo "Setting file permissions..."
/bin/chmod -R 755 "$PAYLOAD" || exit 1

# Build tarball
echo "Building archive..."
pushd "$PAYLOAD"
tar -czvf "$TAROUT" * || exit 1
popd

# Build .deb
INSTALL_TO="$DEBPKG/usr/bin/"
mkdir -p "$DEBPKG/DEBIAN" "$INSTALL_TO"

# make the debian control file
cat >"$DEBPKG/DEBIAN/control" <<EOF
Package: gcmcore
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Question: do we want the package to be gcmcore or gcm-core or git-credential-manager-core?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@mjcheetham I'm guessing we should follow the precedent for the windows and mac distro naming? Which I think is git-credential-manager-core ?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are alias supported? I realise git-credential-manager-core is a mouthful, but it is the official name (and I'm a stickler for formalities 😛)..

Version: $VERSION
Section: vcs
Priority: optional
Architecture: $ARCH
Depends:
Maintainer: GCM-Core <gcmcore@microsoft.com>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this a real email address?

Copy link
Contributor Author

@kyle-rader kyle-rader Sep 11, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not yet. But I figured we should create a legit public support email. Happy to create it and add us as owners. I noticed the email used in creating the git-vfs package uses a fake email like gitvfs@exmaple.com or something.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

gcmsupport@microsoft.com is a real email. We can use this. It forwards to the team.

Copy link
Collaborator

@mjcheetham mjcheetham Sep 14, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh and https://aka.ms/gcmcore is also a short-link that we own (it redirects to the repository page on GitHub). We also own https://github.com/GitCredentialManager, but this organisation cannot host any code repositories but only contact or readme information, per Microsoft OSS policy.

Description: Cross Platform Git-Credential-Manager-Core command line utility.
Linux build of the GCM-Core project to support auth with a number of
git hosting providers including GitHub, BitBucket, and Azure DevOps.
Hosted at https://github.com/microsoft/Git-Credential-Manager-Core
EOF

# Copy single binary to target installation location
cp "$PAYLOAD/git-credential-manager-core" "$INSTALL_TO"

# Layout and pack
"$PAYLOAD_SRC/layout.sh" --configuration="$CONFIGURATION" --output="$PAYLOAD" || exit 1
"$PAYLOAD_SRC/pack.sh" --payload="$PAYLOAD" --output="$TAROUT" || exit 1
dpkg-deb --build "$DEBPKG" "$DEBOUT"

echo "Build of Payload.Linux complete."
echo "Pack complete."
kyle-rader marked this conversation as resolved.
Show resolved Hide resolved
79 changes: 0 additions & 79 deletions src/linux/Payload.Linux/layout.sh

This file was deleted.

59 changes: 0 additions & 59 deletions src/linux/Payload.Linux/pack.sh

This file was deleted.