Skip to content

Commit bd9db88

Browse files
committed
Makefile: add Debian packaging targets
Add 'package' target to Makefile that, based on the 'GOOS', builds the platform-appropriate package. For now, support only binary .deb packages (corresponding to a 'GOOS' of 'linux'); if the 'GOOS' is unsupported, 'make' will exit with an error. The .deb packaging process is broken into three steps, each corresponding to a target in the Makefile: 1. Build the executables. 2. Copy the executables & any symlinks into the appropriate file structure for running 'dpkg-deb'. 3. Generate the control file, copy the maintainer script(s) [1], and build the package with 'dpkg-deb'. Additionally, the 'check-arch' and 'check-version' targets verify that the 'GOARCH' is supported for packaging on the platform and that a version string is set, respectively. [1] https://www.debian.org/doc/debian-policy/ap-flowcharts.html Signed-off-by: Victoria Dye <[email protected]>
1 parent 1aa748c commit bd9db88

File tree

6 files changed

+239
-1
lines changed

6 files changed

+239
-1
lines changed

.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
/git-bundle-server
22
/git-bundle-web-server
33
/bin/
4+
/_dist/

.vscode/settings.json

+18-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,24 @@
66
"editor.wordWrap": "off",
77
"files.trimTrailingWhitespace": true,
88
},
9+
"[makefile]": {
10+
"editor.detectIndentation": false,
11+
"editor.insertSpaces": false,
12+
"editor.tabSize": 8,
13+
"editor.wordWrap": "off",
14+
"files.trimTrailingWhitespace": true,
15+
},
16+
"[shellscript]": {
17+
"editor.detectIndentation": false,
18+
"editor.insertSpaces": false,
19+
"editor.tabSize": 8,
20+
"editor.wordWrap": "off",
21+
"files.trimTrailingWhitespace": true,
22+
},
923
"files.associations": {
10-
"*.md": "markdown"
24+
"*.md": "markdown",
25+
"*.sh": "shellscript",
26+
"prerm": "shellscript",
27+
"Makefile": "makefile"
1128
}
1229
}

Makefile

+61
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,83 @@
11
# Default target
22
build:
33

4+
# Project metadata (note: to package, VERSION *must* be set by the caller)
5+
NAME := git-bundle-server
6+
VERSION :=
7+
PACKAGE_REVISION := 1
8+
49
# Helpful paths
510
BINDIR := $(CURDIR)/bin
11+
DISTDIR := $(CURDIR)/_dist
612

713
# Platform information
814
GOOS := $(shell go env GOOS)
915
GOARCH := $(shell go env GOARCH)
1016

17+
# Packaging information
18+
SUPPORTED_PACKAGE_GOARCHES := amd64 arm64
19+
PACKAGE_ARCH := $(GOARCH)
20+
1121
# Build targets
1222
.PHONY: build
1323
build:
1424
$(RM) -r $(BINDIR)
1525
@mkdir -p $(BINDIR)
1626
GOOS="$(GOOS)" GOARCH="$(GOARCH)" go build -o $(BINDIR) ./...
1727

28+
# Packaging targets
29+
.PHONY: check-arch
30+
check-arch:
31+
$(if $(filter $(GOARCH),$(SUPPORTED_PACKAGE_GOARCHES)), , \
32+
$(error cannot create package for GOARCH "$(GOARCH)"; \
33+
supported architectures are: $(SUPPORTED_PACKAGE_GOARCHES)))
34+
35+
.PHONY: check-version
36+
check-version:
37+
$(if $(VERSION), , $(error version is undefined))
38+
39+
ifeq ($(GOOS),linux)
40+
# Linux binary .deb file
41+
# Steps:
42+
# 1. Layout files in _dist/deb/root/ as they'll be installed (unlike MacOS
43+
# .pkg packages, symlinks created in the payload are preserved, so we
44+
# create them here to avoid doing so in a post-install step).
45+
# 2. Create the binary deb package in _dist/deb/.
46+
47+
# Platform-specific variables
48+
DEBDIR := $(DISTDIR)/deb
49+
DEB_FILENAME := $(DISTDIR)/$(NAME)_$(VERSION)-$(PACKAGE_REVISION)_$(PACKAGE_ARCH).deb
50+
51+
# Targets
52+
$(DEBDIR)/root: check-arch build
53+
@echo
54+
@echo "======== Formatting package contents ========"
55+
@build/package/layout-unix.sh --bindir="$(BINDIR)" \
56+
--include-symlinks \
57+
--output="$(DEBDIR)/root"
58+
59+
$(DEB_FILENAME): check-version $(DEBDIR)/root
60+
@echo
61+
@echo "======== Creating binary Debian package ========"
62+
@build/package/deb/pack.sh --payload="$(DEBDIR)/root" \
63+
--arch="$(PACKAGE_ARCH)" \
64+
--version="$(VERSION)" \
65+
--output="$(DEB_FILENAME)"
66+
67+
.PHONY: package
68+
package: $(DEB_FILENAME)
69+
70+
else
71+
# Packaging not supported for platform, exit with error.
72+
.PHONY: package
73+
package:
74+
$(error cannot create package for GOOS "$(GOOS)")
75+
76+
endif
77+
1878
# Cleanup targets
1979
.PHONY: clean
2080
clean:
2181
go clean ./...
2282
$(RM) -r $(BINDIR)
83+
$(RM) -r $(DISTDIR)

build/package/deb/pack.sh

+82
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
#!/bin/bash
2+
die () {
3+
echo "$*" >&2
4+
exit 1
5+
}
6+
7+
# Directories
8+
THISDIR="$( cd "$(dirname "$0")" ; pwd -P )"
9+
10+
# Local paths
11+
UNINSTALLER="$THISDIR/uninstall.sh"
12+
13+
# Parse script arguments
14+
for i in "$@"
15+
do
16+
case "$i" in
17+
--payload=*)
18+
DEBROOT="${i#*=}"
19+
shift # past argument=value
20+
;;
21+
--arch=*)
22+
ARCH="${i#*=}"
23+
shift # past argument=value
24+
;;
25+
--version=*)
26+
VERSION="${i#*=}"
27+
shift # past argument=value
28+
;;
29+
--output=*)
30+
DEBOUT="${i#*=}"
31+
shift # past argument=value
32+
;;
33+
*)
34+
die "unknown option '$i'"
35+
;;
36+
esac
37+
done
38+
39+
# Perform pre-execution checks
40+
if [ -z "$DEBROOT" ]; then
41+
die "--payload was not set"
42+
elif [ ! -d "$DEBROOT" ]; then
43+
die "Could not find '$DEBROOT'. Did you run layout-unix.sh first?"
44+
fi
45+
if [ -z "$ARCH" ]; then
46+
die "--arch was not set"
47+
fi
48+
if [ -z "$VERSION" ]; then
49+
die "--version was not set"
50+
fi
51+
if [ -z "$DEBOUT" ]; then
52+
die "--output was not set"
53+
fi
54+
55+
# Exit as soon as any line fails
56+
set -e
57+
58+
# Cleanup old package
59+
if [ -e "$DEBOUT" ]; then
60+
echo "Deleting old package '$DEBOUT'..."
61+
rm -f "$DEBOUT"
62+
fi
63+
64+
# Ensure the parent directory for the component exists
65+
mkdir -p "$(dirname "$DEBOUT")"
66+
67+
# Build .deb
68+
mkdir -p "$DEBROOT/DEBIAN"
69+
70+
# Create the debian control file
71+
cat >"$DEBROOT/DEBIAN/control" <<EOF
72+
Package: git-bundle-server
73+
Version: $VERSION
74+
Section: vcs
75+
Priority: optional
76+
Architecture: $ARCH
77+
Depends:
78+
Maintainer: Git Bundle Server <[email protected]>
79+
Description: A self-hostable Git bundle server.
80+
EOF
81+
82+
dpkg-deb -Zxz --build "$DEBROOT" "$DEBOUT"

build/package/deb/scripts/prerm

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
#!/bin/bash
2+
set -e
3+
4+
# Stop & cleanup the web server
5+
/usr/local/git-bundle-server/bin/git-bundle-server web-server stop --remove
6+
7+
exit 0

build/package/layout-unix.sh

+70
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
#!/bin/bash
2+
die () {
3+
echo "$*" >&2
4+
exit 1
5+
}
6+
7+
# Parse script arguments
8+
for i in "$@"
9+
do
10+
case "$i" in
11+
--bindir=*)
12+
BINDIR="${i#*=}"
13+
shift # past argument=value
14+
;;
15+
--include-symlinks)
16+
INCLUDE_SYMLINKS=1
17+
shift # past argument
18+
;;
19+
--output=*)
20+
PAYLOAD="${i#*=}"
21+
shift # past argument=value
22+
;;
23+
*)
24+
die "unknown option '$i'"
25+
;;
26+
esac
27+
done
28+
29+
# Perform pre-execution checks
30+
if [ -z "$BINDIR" ]; then
31+
die "--bindir was not set"
32+
fi
33+
if [ -z "$PAYLOAD" ]; then
34+
die "--output was not set"
35+
fi
36+
37+
# Exit as soon as any line fails
38+
set -e
39+
40+
# Cleanup any old payload directory
41+
if [ -d "$PAYLOAD" ]; then
42+
echo "Cleaning old output directory '$PAYLOAD'..."
43+
rm -rf "$PAYLOAD"
44+
fi
45+
46+
# Ensure payload directory exists
47+
INSTALL_TO="$PAYLOAD/usr/local/git-bundle-server/"
48+
mkdir -p "$INSTALL_TO"
49+
50+
# Copy built binaries
51+
echo "Copying binaries..."
52+
cp -R "$BINDIR/." "$INSTALL_TO/bin"
53+
54+
# Create symlinks
55+
if [ -n "$INCLUDE_SYMLINKS" ]; then
56+
LINK_TO="$DEBROOT/usr/local/bin/"
57+
mkdir -p "$LINK_TO"
58+
59+
echo "Creating symlinks..."
60+
for program in "$INSTALL_TO"/bin/*
61+
do
62+
ln -s -r "$program" "$LINK_TO/$(basename $program)"
63+
done
64+
fi
65+
66+
# Remove any unwanted .DS_Store files
67+
echo "Removing unnecessary files..."
68+
find "$PAYLOAD" -name '*.DS_Store' -type f -delete
69+
70+
echo "Layout complete."

0 commit comments

Comments
 (0)