246 lines
7 KiB
Bash
Executable file
246 lines
7 KiB
Bash
Executable file
#!/bin/bash
|
|
set -euo pipefail
|
|
|
|
# c65gm Release Builder
|
|
#
|
|
# Fully automated release process:
|
|
# 1. Verifies git working tree is clean
|
|
# 2. Reads BUILDNUM, derives version (MAJOR.BUILDNUM)
|
|
# 3. Verifies the tag doesn't already exist
|
|
# 4. Bumps BUILDNUM
|
|
# 5. Builds all target binaries (embedded lib, version injected)
|
|
# 6. Generates SHA256 checksums
|
|
# 7. Commits the BUILDNUM bump (with checksums in commit body)
|
|
# 8. Creates an annotated tag pointing at PRE-bump commit
|
|
# (tag message contains checksums + build info for verification)
|
|
#
|
|
# To publish the release:
|
|
# git push --follow-tags origin
|
|
|
|
MAJOR=1
|
|
|
|
print_ok() { echo " [OK] $1"; }
|
|
print_err() { echo " [ERROR] $1" >&2; }
|
|
|
|
echo ""
|
|
echo "=== c65gm Release Builder ==="
|
|
echo ""
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# 1. Verify git working tree is clean
|
|
# ---------------------------------------------------------------------------
|
|
if [ -n "$(git status --porcelain 2>/dev/null)" ]; then
|
|
echo ""
|
|
git status --short
|
|
echo ""
|
|
print_err "working tree is not clean — commit or stash changes first"
|
|
exit 1
|
|
fi
|
|
print_ok "Working tree is clean"
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# 2. Read BUILDNUM
|
|
# ---------------------------------------------------------------------------
|
|
if [ ! -f BUILDNUM ]; then
|
|
echo "1" > BUILDNUM
|
|
fi
|
|
|
|
BUILDNUM=$(cat BUILDNUM)
|
|
VERSION="${MAJOR}.${BUILDNUM}"
|
|
TAG="v${VERSION}"
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# 3. Verify tag doesn't already exist
|
|
# ---------------------------------------------------------------------------
|
|
if git rev-parse --quiet --verify "refs/tags/${TAG}" >/dev/null 2>&1; then
|
|
print_err "tag ${TAG} already exists — bump BUILDNUM manually if needed"
|
|
exit 1
|
|
fi
|
|
print_ok "Tag ${TAG} is available"
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# 4. Save source commit (before any changes)
|
|
# ---------------------------------------------------------------------------
|
|
SOURCE_COMMIT=$(git rev-parse HEAD)
|
|
if [ -z "$SOURCE_COMMIT" ]; then
|
|
print_err "could not determine HEAD commit"
|
|
exit 1
|
|
fi
|
|
|
|
echo ""
|
|
echo " Version: ${TAG}"
|
|
echo " Source: ${SOURCE_COMMIT}"
|
|
echo " BUILDNUM: ${BUILDNUM} (bumps to $((BUILDNUM + 1)))"
|
|
echo ""
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# 5. Bump BUILDNUM
|
|
# ---------------------------------------------------------------------------
|
|
NEXT_BUILDNUM=$((BUILDNUM + 1))
|
|
echo "${NEXT_BUILDNUM}" > BUILDNUM
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# 6. Copy lib for embedding
|
|
# ---------------------------------------------------------------------------
|
|
echo " Preparing embedded library..."
|
|
rm -rf internal/preproc/lib
|
|
cp -r lib internal/preproc/
|
|
print_ok "Library copied for embedding"
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# Build metadata
|
|
# ---------------------------------------------------------------------------
|
|
GO_VERSION="$(go version 2>/dev/null || echo 'unknown')"
|
|
BUILD_DATE="$(date -u +%Y-%m-%dT%H:%M:%SZ 2>/dev/null || date -u +%Y-%m-%d)"
|
|
|
|
LDFLAGS="-s -w -X main.version=${VERSION}"
|
|
DIST="dist"
|
|
rm -rf "$DIST"
|
|
mkdir -p "$DIST"
|
|
|
|
# SHA256 command detection (Linux vs macOS)
|
|
SHA_CMD=""
|
|
if command -v sha256sum &>/dev/null; then
|
|
SHA_CMD="sha256sum"
|
|
elif command -v shasum &>/dev/null; then
|
|
SHA_CMD="shasum -a 256"
|
|
else
|
|
print_err "no sha256sum or shasum command found"
|
|
exit 1
|
|
fi
|
|
|
|
# Targets
|
|
TARGETS=(
|
|
"linux/amd64"
|
|
"linux/arm64"
|
|
"darwin/amd64"
|
|
"darwin/arm64"
|
|
"windows/amd64"
|
|
)
|
|
|
|
echo ""
|
|
echo " Building targets: ${TARGETS[*]}"
|
|
echo ""
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# 7. Build all targets
|
|
# ---------------------------------------------------------------------------
|
|
BUILD_DIR="$(mktemp -d)"
|
|
trap 'rm -rf "$BUILD_DIR"' EXIT
|
|
|
|
for target in "${TARGETS[@]}"; do
|
|
GOOS="${target%%/*}"
|
|
GOARCH="${target##*/}"
|
|
|
|
bin_name="c65gm"
|
|
[ "$GOOS" = "windows" ] && bin_name="c65gm.exe"
|
|
|
|
echo " ${target}..."
|
|
|
|
GOOS=$GOOS GOARCH=$GOARCH CGO_ENABLED=0 \
|
|
go build -trimpath -ldflags="$LDFLAGS" -o "${BUILD_DIR}/${bin_name}"
|
|
|
|
archive_name="c65gm_v${VERSION}_${GOOS}_${GOARCH}"
|
|
if [ "$GOOS" = "windows" ]; then
|
|
(cd "$BUILD_DIR" && zip -q "${OLDPWD}/${DIST}/${archive_name}.zip" "$bin_name")
|
|
echo " => ${DIST}/${archive_name}.zip"
|
|
else
|
|
tar -czf "${DIST}/${archive_name}.tar.gz" -C "$BUILD_DIR" "$bin_name"
|
|
echo " => ${DIST}/${archive_name}.tar.gz"
|
|
fi
|
|
|
|
rm -f "${BUILD_DIR}/${bin_name}"
|
|
done
|
|
|
|
echo ""
|
|
print_ok "All targets built"
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# 8. Generate checksums
|
|
# ---------------------------------------------------------------------------
|
|
echo ""
|
|
echo "=== SHA256 checksums ==="
|
|
echo ""
|
|
(
|
|
cd "$DIST"
|
|
$SHA_CMD * > checksums.txt
|
|
cat checksums.txt
|
|
)
|
|
|
|
CHECKSUMS_TEXT="$(cat "${DIST}/checksums.txt")"
|
|
print_ok "Checksums generated"
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# 9. Commit BUILDNUM bump
|
|
# ---------------------------------------------------------------------------
|
|
echo ""
|
|
echo "=== Creating commit ==="
|
|
|
|
COMMIT_MSG=$(cat << COMMIT_EOF
|
|
${TAG}
|
|
|
|
Built with: ${GO_VERSION}
|
|
Build date: ${BUILD_DATE}
|
|
|
|
SHA256 checksums:
|
|
${CHECKSUMS_TEXT}
|
|
COMMIT_EOF
|
|
)
|
|
|
|
git add BUILDNUM
|
|
git commit -m "$COMMIT_MSG"
|
|
print_ok "Commit created (BUILDNUM bumped to ${NEXT_BUILDNUM})"
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# 10. Create annotated tag pointing at source commit
|
|
# ---------------------------------------------------------------------------
|
|
echo ""
|
|
echo "=== Creating tag ==="
|
|
|
|
TAG_MSG=$(cat << TAG_EOF
|
|
c65gm ${TAG}
|
|
|
|
Built with: ${GO_VERSION}
|
|
Build date: ${BUILD_DATE}
|
|
|
|
SHA256 checksums:
|
|
${CHECKSUMS_TEXT}
|
|
|
|
To reproduce this build:
|
|
git checkout ${TAG}
|
|
go build -trimpath -ldflags="${LDFLAGS}"
|
|
|
|
Then verify:
|
|
sha256sum c65gm
|
|
TAG_EOF
|
|
)
|
|
|
|
git tag -a "$TAG" "$SOURCE_COMMIT" -m "$TAG_MSG"
|
|
print_ok "Tag ${TAG} created (pointing at ${SOURCE_COMMIT})"
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# 11. Summary
|
|
# ---------------------------------------------------------------------------
|
|
echo ""
|
|
echo "============================================"
|
|
echo " c65gm ${TAG} released!"
|
|
echo ""
|
|
echo " Source commit: ${SOURCE_COMMIT}"
|
|
echo " BUILDNUM: ${BUILDNUM} → ${NEXT_BUILDNUM}"
|
|
echo " Artifacts in: ${DIST}/"
|
|
echo " Go version: ${GO_VERSION}"
|
|
echo ""
|
|
echo " !!! IMPORTANT !!!"
|
|
echo " The tag '${TAG}' exists ONLY on your machine."
|
|
echo " It must be pushed separately to make it available."
|
|
echo ""
|
|
echo " To publish the complete release:"
|
|
echo " git push --follow-tags origin"
|
|
echo ""
|
|
echo " If you already pushed without --follow-tags:"
|
|
echo " git push origin ${TAG}"
|
|
echo ""
|
|
echo " Artifacts:"
|
|
ls -lh "${DIST}/" | sed 's/^/ /'
|
|
echo "============================================"
|
|
echo ""
|