295 lines
8.2 KiB
Bash
Executable File
295 lines
8.2 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# release.sh — Verstak release script
|
|
# Builds all binaries, packages, signs Firefox XPI, creates git tag.
|
|
#
|
|
# Usage:
|
|
# ./scripts/release.sh # Full release (requires AMO tokens for Firefox signing)
|
|
# ./scripts/release.sh --skip-firefox-sign # Skip Firefox XPI signing
|
|
# ./scripts/release.sh --publish # Push git tag + create GitHub release
|
|
# ./scripts/release.sh --help # Show usage
|
|
set -euo pipefail
|
|
|
|
ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
|
cd "$ROOT_DIR"
|
|
|
|
# --- Config ---
|
|
SKIP_FIREFOX_SIGN=false
|
|
PUBLISH=false
|
|
for arg in "$@"; do
|
|
case "$arg" in
|
|
--skip-firefox-sign) SKIP_FIREFOX_SIGN=true ;;
|
|
--publish) PUBLISH=true ;;
|
|
--help)
|
|
echo "Usage: $0 [--skip-firefox-sign] [--publish]"
|
|
echo ""
|
|
echo " --skip-firefox-sign Skip Firefox extension signing (fails by default if AMO tokens missing)"
|
|
echo " --publish Push git tag and create GitHub release"
|
|
exit 0
|
|
;;
|
|
esac
|
|
done
|
|
|
|
VERSION="$(cat VERSION 2>/dev/null || echo "0.1.0-dev")"
|
|
RELEASE_DIR="release"
|
|
LINUX_DIR="$RELEASE_DIR/linux"
|
|
BUILD_DIR="build"
|
|
|
|
echo "============================================"
|
|
echo " Verstak Release v$VERSION"
|
|
echo "============================================"
|
|
echo ""
|
|
|
|
# --- Pre-flight checks ---
|
|
echo "==> Pre-flight checks..."
|
|
|
|
if ! git diff --quiet --exit-code 2>/dev/null; then
|
|
echo "ERROR: working tree is dirty. Commit or stash changes first."
|
|
git diff --stat
|
|
exit 1
|
|
fi
|
|
|
|
if ! git diff --cached --quiet --exit-code 2>/dev/null; then
|
|
echo "ERROR: staged but uncommitted changes. Commit first."
|
|
exit 1
|
|
fi
|
|
|
|
echo " Working tree clean ✓"
|
|
|
|
if ! go version &>/dev/null; then
|
|
echo "ERROR: go not found"
|
|
exit 1
|
|
fi
|
|
|
|
echo " Go: $(go version)"
|
|
|
|
# --- Run tests ---
|
|
echo ""
|
|
echo "==> Running tests..."
|
|
go vet ./...
|
|
go test ./... -count=1
|
|
echo " Tests: all passed ✓"
|
|
|
|
# --- Build ---
|
|
echo ""
|
|
echo "==> Building all binaries..."
|
|
mkdir -p "$BUILD_DIR" "$LINUX_DIR"
|
|
rm -f "$LINUX_DIR"/*
|
|
|
|
./scripts/build.sh release
|
|
echo " Build complete ✓"
|
|
|
|
# --- VERSION file ---
|
|
echo "$VERSION" > "$LINUX_DIR/VERSION"
|
|
|
|
# --- DEB package: GUI ---
|
|
echo ""
|
|
echo "==> Building DEB packages..."
|
|
build_deb() {
|
|
local binary="$1"
|
|
local pkg_name="$2"
|
|
local description="$3"
|
|
local systemd_unit="${4:-}"
|
|
|
|
local deb_dir="$BUILD_DIR/deb-tmp/$pkg_name"
|
|
mkdir -p "$deb_dir/DEBIAN"
|
|
mkdir -p "$deb_dir/usr/local/bin"
|
|
mkdir -p "$deb_dir/usr/share/doc/$pkg_name"
|
|
|
|
cp "$BUILD_DIR/$binary" "$deb_dir/usr/local/bin/$pkg_name"
|
|
chmod 755 "$deb_dir/usr/local/bin/$pkg_name"
|
|
|
|
if [[ -n "$systemd_unit" && -f "$systemd_unit" ]]; then
|
|
mkdir -p "$deb_dir/lib/systemd/system"
|
|
cp "$systemd_unit" "$deb_dir/lib/systemd/system/"
|
|
fi
|
|
|
|
# Simple control file
|
|
cat > "$deb_dir/DEBIAN/control" <<CTRL
|
|
Package: $pkg_name
|
|
Version: $VERSION
|
|
Section: utils
|
|
Priority: optional
|
|
Architecture: amd64
|
|
Maintainer: Verstak <verstak@mirv.top>
|
|
Description: $description
|
|
CTRL
|
|
|
|
# Copy README if exists
|
|
[[ -f "README.md" ]] && cp "README.md" "$deb_dir/usr/share/doc/$pkg_name/"
|
|
|
|
dpkg-deb --root-owner-group --build "$deb_dir" "$LINUX_DIR/${pkg_name}.deb" >/dev/null
|
|
rm -rf "$BUILD_DIR/deb-tmp"
|
|
echo " $LINUX_DIR/${pkg_name}.deb"
|
|
}
|
|
|
|
build_deb "verstak" "verstak" "Verstak — local-first working vault GUI"
|
|
build_deb "verstak-server" "verstak-server" "Verstak Sync Server" "cmd/verstak-server/verstak-server.service"
|
|
|
|
# --- RPM package: GUI ---
|
|
echo ""
|
|
echo "==> Building RPM packages..."
|
|
build_rpm() {
|
|
local binary="$1"
|
|
local pkg_name="$2"
|
|
local description="$3"
|
|
local systemd_unit="${4:-}"
|
|
|
|
local rpm_dir="$BUILD_DIR/rpm-tmp"
|
|
mkdir -p "$rpm_dir/RPMS/x86_64"
|
|
mkdir -p "$rpm_dir/BUILD"
|
|
mkdir -p "$rpm_dir/SOURCES"
|
|
|
|
# Build root for rpmbuild
|
|
local buildroot="$rpm_dir/buildroot"
|
|
mkdir -p "$buildroot/usr/local/bin"
|
|
mkdir -p "$buildroot/usr/share/doc/$pkg_name"
|
|
|
|
cp "$BUILD_DIR/$binary" "$buildroot/usr/local/bin/$pkg_name"
|
|
chmod 755 "$buildroot/usr/local/bin/$pkg_name"
|
|
|
|
if [[ -n "$systemd_unit" && -f "$systemd_unit" ]]; then
|
|
mkdir -p "$buildroot/lib/systemd/system"
|
|
cp "$systemd_unit" "$buildroot/lib/systemd/system/"
|
|
fi
|
|
|
|
[[ -f "README.md" ]] && cp "README.md" "$buildroot/usr/share/doc/$pkg_name/"
|
|
|
|
# File list
|
|
local file_list
|
|
file_list="%attr(755, root, root) /usr/local/bin/$pkg_name"
|
|
file_list+="%attr(644, root, root) /usr/share/doc/$pkg_name/*"
|
|
if [[ -n "$systemd_unit" && -f "$systemd_unit" ]]; then
|
|
# systemd file will be included via %files section
|
|
file_list+="%attr(644, root, root) /lib/systemd/system/$(basename "$systemd_unit")"
|
|
fi
|
|
|
|
local spec_file="$rpm_dir/SPECS/${pkg_name}.spec"
|
|
mkdir -p "$(dirname "$spec_file")"
|
|
|
|
cat > "$spec_file" <<SPEC
|
|
Summary: $description
|
|
Name: $pkg_name
|
|
Version: $VERSION
|
|
Release: 1
|
|
License: MIT
|
|
Group: Utilities
|
|
BuildArch: x86_64
|
|
AutoReqProv: no
|
|
Prefix: /usr
|
|
|
|
%description
|
|
$description
|
|
|
|
%install
|
|
rm -rf %{buildroot}
|
|
mkdir -p %{buildroot}/usr/local/bin
|
|
cp $BUILD_DIR/$binary %{buildroot}/usr/local/bin/$pkg_name
|
|
chmod 755 %{buildroot}/usr/local/bin/$pkg_name
|
|
SPEC
|
|
|
|
if [[ -n "$systemd_unit" && -f "$systemd_unit" ]]; then
|
|
cat >> "$spec_file" <<SPEC
|
|
mkdir -p %{buildroot}/lib/systemd/system
|
|
cp $systemd_unit %{buildroot}/lib/systemd/system/
|
|
SPEC
|
|
fi
|
|
|
|
cat >> "$spec_file" <<SPEC
|
|
mkdir -p %{buildroot}/usr/share/doc/$pkg_name
|
|
cp -r README.md %{buildroot}/usr/share/doc/$pkg_name/ 2>/dev/null || true
|
|
|
|
%files
|
|
/usr/local/bin/$pkg_name
|
|
SPEC
|
|
|
|
if [[ -n "$systemd_unit" && -f "$systemd_unit" ]]; then
|
|
echo "/lib/systemd/system/$(basename "$systemd_unit")" >> "$spec_file"
|
|
fi
|
|
|
|
cat >> "$spec_file" <<SPEC
|
|
%doc /usr/share/doc/$pkg_name/*
|
|
SPEC
|
|
|
|
rpmbuild --define "_topdir $rpm_dir" \
|
|
--define "_builddir $rpm_dir/BUILD" \
|
|
--define "_sourcedir $rpm_dir/SOURCES" \
|
|
--define "_rpmdir $rpm_dir/RPMS" \
|
|
--define "_specdir $rpm_dir/SPECS" \
|
|
--define "_buildrootdir $rpm_dir/buildroot" \
|
|
-bb "$spec_file" >/dev/null
|
|
|
|
cp "$rpm_dir/RPMS/x86_64/${pkg_name}-${VERSION}-1.x86_64.rpm" \
|
|
"$LINUX_DIR/${pkg_name}.rpm"
|
|
rm -rf "$rpm_dir"
|
|
echo " $LINUX_DIR/${pkg_name}.rpm"
|
|
}
|
|
|
|
build_rpm "verstak" "verstak" "Verstak — local-first working vault GUI"
|
|
build_rpm "verstak-server" "verstak-server" "Verstak Sync Server" "cmd/verstak-server/verstak-server.service"
|
|
|
|
# --- Firefox signed XPI ---
|
|
echo ""
|
|
if [[ "$SKIP_FIREFOX_SIGN" == "true" ]]; then
|
|
echo "==> Firefox extension signing skipped (--skip-firefox-sign)"
|
|
elif [[ -f ".env" ]] && grep -q "WEB_EXT_API_KEY" ".env" 2>/dev/null; then
|
|
echo "==> Signing Firefox extension..."
|
|
./scripts/release-firefox-xpi.sh
|
|
else
|
|
echo "ERROR: AMO tokens not found (WEB_EXT_API_KEY / WEB_EXT_API_SECRET in .env)." >&2
|
|
echo " Firefox signing is required for a full release." >&2
|
|
echo " To skip: run with --skip-firefox-sign" >&2
|
|
echo " To sign: copy .env.example -> .env and fill in AMO credentials from" >&2
|
|
echo " https://addons.mozilla.org/developers/" >&2
|
|
exit 1
|
|
fi
|
|
|
|
# --- Checksums ---
|
|
echo ""
|
|
echo "==> Generating checksums..."
|
|
cd "$LINUX_DIR"
|
|
sha256sum verstak verstak-server *.deb *.rpm 2>/dev/null > checksums.txt || true
|
|
cd "$ROOT_DIR"
|
|
echo " $LINUX_DIR/checksums.txt"
|
|
|
|
# --- Summary ---
|
|
echo ""
|
|
echo "============================================"
|
|
echo " Release v$VERSION artifacts"
|
|
echo "============================================"
|
|
echo ""
|
|
echo "Linux binaries:"
|
|
ls -lh "$LINUX_DIR/" 2>/dev/null
|
|
echo ""
|
|
|
|
if [[ -d "$RELEASE_DIR/firefox" ]]; then
|
|
echo "Firefox extension:"
|
|
ls -lh "$RELEASE_DIR/firefox/" 2>/dev/null
|
|
echo ""
|
|
fi
|
|
|
|
echo "============================================"
|
|
|
|
# --- Git tag + release ---
|
|
if [[ "$PUBLISH" == "true" ]]; then
|
|
echo ""
|
|
echo "==> Creating git tag v$VERSION..."
|
|
git tag -s "v$VERSION" -m "Verstak v$VERSION"
|
|
git push origin "v$VERSION"
|
|
|
|
echo "==> Creating GitHub release..."
|
|
gh release create "v$VERSION" \
|
|
--title "Verstak v$VERSION" \
|
|
--notes "See CHANGELOG.md for details" \
|
|
"$LINUX_DIR"/* \
|
|
$([[ -d "$RELEASE_DIR/firefox" ]] && echo "$RELEASE_DIR/firefox/"* || true)
|
|
|
|
echo " GitHub release created: https://github.com/$(git remote get-url origin | sed 's|.*github.com[:/]||;s|\\.git$||')/releases/tag/v$VERSION"
|
|
else
|
|
echo ""
|
|
echo "Dry-run: use --publish to create git tag + GitHub release."
|
|
echo "Run: git tag -s v$VERSION -m \"Verstak v$VERSION\""
|
|
fi
|
|
|
|
echo ""
|
|
echo "Done."
|