diff --git a/.gitea/workflows/ci.yml b/.gitea/workflows/ci.yml index d1ef473..d0956e1 100644 --- a/.gitea/workflows/ci.yml +++ b/.gitea/workflows/ci.yml @@ -250,11 +250,14 @@ jobs: if: failure() run: cat /tmp/mcplocal.log || true - # ── Build & package RPM ─────────────────────────────────── + # ── Build & package (both amd64 and arm64) ────────────── build: runs-on: ubuntu-latest needs: [lint, typecheck, test] + strategy: + matrix: + arch: [amd64, arm64] steps: - uses: actions/checkout@v4 @@ -283,11 +286,18 @@ jobs: - name: Install nfpm run: | + # nfpm itself runs on the CI runner (always x86_64); it cross-packages + # for the target arch via NFPM_ARCH env var — no ARM nfpm binary needed. curl -sL -o /tmp/nfpm.tar.gz "https://github.com/goreleaser/nfpm/releases/download/v2.45.0/nfpm_2.45.0_Linux_x86_64.tar.gz" tar xzf /tmp/nfpm.tar.gz -C /usr/local/bin nfpm - - name: Bundle standalone binaries + - name: Bundle standalone binaries (${{ matrix.arch }}) + env: + MCPCTL_TARGET_ARCH: ${{ matrix.arch }} run: | + source scripts/arch-helper.sh + resolve_arch "$MCPCTL_TARGET_ARCH" + mkdir -p dist # Stub for optional dep that Ink tries to import (only used when DEV=true) # Copy instead of symlink — bun can't read directory symlinks @@ -295,26 +305,30 @@ jobs: rm -rf node_modules/react-devtools-core cp -r src/cli/stubs/react-devtools-core node_modules/react-devtools-core fi - bun build src/cli/src/index.ts --compile --outfile dist/mcpctl - bun build src/mcplocal/src/main.ts --compile --outfile dist/mcpctl-local + bun build src/cli/src/index.ts --compile ${BUN_TARGET:+--target "$BUN_TARGET"} --outfile dist/mcpctl + bun build src/mcplocal/src/main.ts --compile ${BUN_TARGET:+--target "$BUN_TARGET"} --outfile dist/mcpctl-local - - name: Package RPM + - name: Package RPM (${{ matrix.arch }}) + env: + NFPM_ARCH: ${{ matrix.arch }} run: nfpm pkg --packager rpm --target dist/ - - name: Package DEB + - name: Package DEB (${{ matrix.arch }}) + env: + NFPM_ARCH: ${{ matrix.arch }} run: nfpm pkg --packager deb --target dist/ - name: Upload RPM artifact uses: actions/upload-artifact@v3 with: - name: rpm-package + name: rpm-package-${{ matrix.arch }} path: dist/mcpctl-*.rpm retention-days: 7 - name: Upload DEB artifact uses: actions/upload-artifact@v3 with: - name: deb-package + name: deb-package-${{ matrix.arch }} path: dist/mcpctl*.deb retention-days: 7 @@ -328,19 +342,22 @@ jobs: runs-on: ubuntu-latest needs: [build] if: github.ref == 'refs/heads/main' && github.event_name == 'push' + strategy: + matrix: + arch: [amd64, arm64] steps: - uses: actions/checkout@v4 - name: Download RPM artifact uses: actions/download-artifact@v3 with: - name: rpm-package + name: rpm-package-${{ matrix.arch }} path: dist/ - name: Install rpm tools run: sudo apt-get update && sudo apt-get install -y rpm - - name: Publish RPM to Gitea + - name: Publish RPM (${{ matrix.arch }}) to Gitea env: GITEA_TOKEN: ${{ secrets.PACKAGES_TOKEN }} GITEA_URL: http://${{ env.GITEA_REGISTRY }} @@ -379,16 +396,19 @@ jobs: runs-on: ubuntu-latest needs: [build] if: github.ref == 'refs/heads/main' && github.event_name == 'push' + strategy: + matrix: + arch: [amd64, arm64] steps: - uses: actions/checkout@v4 - name: Download DEB artifact uses: actions/download-artifact@v3 with: - name: deb-package + name: deb-package-${{ matrix.arch }} path: dist/ - - name: Publish DEB to Gitea + - name: Publish DEB (${{ matrix.arch }}) to Gitea env: GITEA_TOKEN: ${{ secrets.PACKAGES_TOKEN }} GITEA_URL: http://${{ env.GITEA_REGISTRY }} diff --git a/installlocal.sh b/installlocal.sh index 3c07dd7..d956e2a 100755 --- a/installlocal.sh +++ b/installlocal.sh @@ -1,23 +1,69 @@ #!/bin/bash -# Build (if needed) and install mcpctl RPM locally +# Build (if needed) and install mcpctl locally. +# Auto-detects package format: RPM for Fedora/RHEL, DEB for Debian/Ubuntu. +# +# Usage: +# ./installlocal.sh # Build and install for native arch +# MCPCTL_TARGET_ARCH=amd64 ./installlocal.sh # Cross-compile for amd64 set -e SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" cd "$SCRIPT_DIR" -RPM_FILE=$(ls dist/mcpctl-*.rpm 2>/dev/null | head -1) +# Resolve target architecture +source scripts/arch-helper.sh +resolve_arch "${MCPCTL_TARGET_ARCH:-}" -# Build if no RPM exists or if source is newer than the RPM -if [[ -z "$RPM_FILE" ]] || [[ $(find src/ -name '*.ts' -newer "$RPM_FILE" 2>/dev/null | head -1) ]]; then - echo "==> Building RPM..." - bash scripts/build-rpm.sh - RPM_FILE=$(ls dist/mcpctl-*.rpm 2>/dev/null | head -1) +# Detect package format +if command -v rpm &>/dev/null && command -v dnf &>/dev/null; then + PKG_FORMAT="rpm" +elif command -v dpkg &>/dev/null && command -v apt &>/dev/null; then + PKG_FORMAT="deb" +elif command -v rpm &>/dev/null; then + PKG_FORMAT="rpm" else - echo "==> RPM is up to date: $RPM_FILE" + echo "Error: Neither rpm/dnf nor dpkg/apt found. Unsupported system." + exit 1 fi -echo "==> Installing $RPM_FILE..." -sudo rpm -Uvh --force "$RPM_FILE" +echo "==> Detected package format: $PKG_FORMAT (arch: $NFPM_ARCH)" + +# Find package matching the target architecture +find_pkg() { + local pattern="$1" + # Filter by architecture name in filename + ls $pattern 2>/dev/null | grep -E "[._]${NFPM_ARCH}[._]" | head -1 +} + +if [ "$PKG_FORMAT" = "rpm" ]; then + PKG_FILE=$(find_pkg "dist/mcpctl-*.rpm") + + # Build if no package exists or if source is newer + if [[ -z "$PKG_FILE" ]] || [[ $(find src/ -name '*.ts' -newer "$PKG_FILE" 2>/dev/null | head -1) ]]; then + echo "==> Building RPM..." + bash scripts/build-rpm.sh + PKG_FILE=$(find_pkg "dist/mcpctl-*.rpm") + else + echo "==> RPM is up to date: $PKG_FILE" + fi + + echo "==> Installing $PKG_FILE..." + sudo rpm -Uvh --force "$PKG_FILE" +else + PKG_FILE=$(find_pkg "dist/mcpctl*.deb") + + # Build if no package exists or if source is newer + if [[ -z "$PKG_FILE" ]] || [[ $(find src/ -name '*.ts' -newer "$PKG_FILE" 2>/dev/null | head -1) ]]; then + echo "==> Building DEB..." + bash scripts/build-deb.sh + PKG_FILE=$(find_pkg "dist/mcpctl*.deb") + else + echo "==> DEB is up to date: $PKG_FILE" + fi + + echo "==> Installing $PKG_FILE..." + sudo dpkg -i "$PKG_FILE" || sudo apt-get install -f -y +fi echo "==> Reloading systemd user units..." systemctl --user daemon-reload diff --git a/nfpm.yaml b/nfpm.yaml index e27f048..34ae5fd 100644 --- a/nfpm.yaml +++ b/nfpm.yaml @@ -1,5 +1,5 @@ name: mcpctl -arch: amd64 +arch: ${NFPM_ARCH:-amd64} version: 0.0.1 release: "1" maintainer: michal diff --git a/package.json b/package.json index 47e84ab..a238b35 100644 --- a/package.json +++ b/package.json @@ -20,10 +20,15 @@ "completions:generate": "tsx scripts/generate-completions.ts --write", "completions:check": "tsx scripts/generate-completions.ts --check", "rpm:build": "bash scripts/build-rpm.sh", + "rpm:build:amd64": "MCPCTL_TARGET_ARCH=amd64 bash scripts/build-rpm.sh", + "rpm:build:arm64": "MCPCTL_TARGET_ARCH=arm64 bash scripts/build-rpm.sh", "rpm:publish": "bash scripts/publish-rpm.sh", "deb:build": "bash scripts/build-deb.sh", + "deb:build:amd64": "MCPCTL_TARGET_ARCH=amd64 bash scripts/build-deb.sh", + "deb:build:arm64": "MCPCTL_TARGET_ARCH=arm64 bash scripts/build-deb.sh", "deb:publish": "bash scripts/publish-deb.sh", "release": "bash scripts/release.sh", + "release:both": "bash scripts/release.sh --both-arches", "mcpd:build": "bash scripts/build-mcpd.sh", "mcpd:deploy": "bash deploy.sh", "mcpd:deploy-dry": "bash deploy.sh --dry-run", diff --git a/scripts/arch-helper.sh b/scripts/arch-helper.sh new file mode 100644 index 0000000..74b02e3 --- /dev/null +++ b/scripts/arch-helper.sh @@ -0,0 +1,62 @@ +#!/bin/bash +# Shared architecture detection for build scripts. +# Source this file, then call: resolve_arch [target_arch] +# +# Outputs (exported): +# NFPM_ARCH — nfpm/deb/rpm arch name: "amd64" or "arm64" +# BUN_TARGET — bun cross-compile target (empty if native build) +# ARCH_SUFFIX — filename suffix for cross-compiled binaries (empty if native) + +_detect_native_arch() { + case "$(uname -m)" in + x86_64) echo "amd64" ;; + aarch64) echo "arm64" ;; + arm64) echo "arm64" ;; # macOS reports arm64 + *) echo "amd64" ;; # fallback + esac +} + +_bun_target_for() { + local arch="$1" + case "$arch" in + amd64) echo "bun-linux-x64" ;; + arm64) echo "bun-linux-arm64" ;; + esac +} + +_nfpm_download_arch() { + local arch="$1" + case "$arch" in + amd64) echo "x86_64" ;; + arm64) echo "arm64" ;; + esac +} + +# resolve_arch [override] +# override: "amd64" or "arm64" (optional, auto-detects if empty) +resolve_arch() { + local requested="${1:-}" + local native + native="$(_detect_native_arch)" + + if [ -z "$requested" ]; then + # Native build + NFPM_ARCH="$native" + BUN_TARGET="" + ARCH_SUFFIX="" + else + NFPM_ARCH="$requested" + if [ "$requested" = "$native" ]; then + # Requesting our own arch — native build + BUN_TARGET="" + ARCH_SUFFIX="" + else + # Cross-compilation + BUN_TARGET="$(_bun_target_for "$requested")" + ARCH_SUFFIX="-${requested}" + fi + fi + + export NFPM_ARCH BUN_TARGET ARCH_SUFFIX + echo " Architecture: ${NFPM_ARCH} (native: ${native}${BUN_TARGET:+, cross-compiling via $BUN_TARGET})" +} diff --git a/scripts/build-deb.sh b/scripts/build-deb.sh index d045312..812171b 100755 --- a/scripts/build-deb.sh +++ b/scripts/build-deb.sh @@ -13,8 +13,14 @@ fi # Ensure tools are on PATH export PATH="$HOME/.npm-global/bin:$HOME/.bun/bin:$HOME/.local/bin:$PATH" +# Architecture detection / cross-compilation support +# MCPCTL_TARGET_ARCH overrides native detection (e.g. "amd64" or "arm64") +source "$SCRIPT_DIR/arch-helper.sh" +resolve_arch "${MCPCTL_TARGET_ARCH:-}" +# Sets: NFPM_ARCH, BUN_TARGET, ARCH_SUFFIX + # Check if binaries already exist (build-rpm.sh may have been run first) -if [ ! -f dist/mcpctl ] || [ ! -f dist/mcpctl-local ]; then +if [ ! -f "dist/mcpctl${ARCH_SUFFIX}" ] || [ ! -f "dist/mcpctl-local${ARCH_SUFFIX}" ]; then echo "==> Binaries not found, building from scratch..." echo "" @@ -28,7 +34,7 @@ if [ ! -f dist/mcpctl ] || [ ! -f dist/mcpctl-local ]; then echo "==> Generating shell completions..." pnpm completions:generate - echo "==> Bundling standalone binaries..." + echo "==> Bundling standalone binaries (target: ${NFPM_ARCH})..." mkdir -p dist # Ink optionally imports react-devtools-core which isn't installed. @@ -37,17 +43,28 @@ if [ ! -f dist/mcpctl ] || [ ! -f dist/mcpctl-local ]; then ln -s ../src/cli/stubs/react-devtools-core node_modules/react-devtools-core fi - bun build src/cli/src/index.ts --compile --outfile dist/mcpctl - bun build src/mcplocal/src/main.ts --compile --outfile dist/mcpctl-local + bun build src/cli/src/index.ts --compile ${BUN_TARGET:+--target "$BUN_TARGET"} --outfile "dist/mcpctl${ARCH_SUFFIX}" + bun build src/mcplocal/src/main.ts --compile ${BUN_TARGET:+--target "$BUN_TARGET"} --outfile "dist/mcpctl-local${ARCH_SUFFIX}" else echo "==> Using existing binaries in dist/" fi -echo "==> Packaging DEB..." -rm -f dist/mcpctl-*.deb dist/mcpctl_*.deb +# If cross-compiling, copy arch-suffixed binaries to the names nfpm expects +if [ -n "$ARCH_SUFFIX" ]; then + cp "dist/mcpctl${ARCH_SUFFIX}" dist/mcpctl + cp "dist/mcpctl-local${ARCH_SUFFIX}" dist/mcpctl-local +fi + +echo "==> Packaging DEB (arch: ${NFPM_ARCH})..." +# Only remove DEBs for the target arch (preserve cross-compiled packages) +ls dist/mcpctl*_${NFPM_ARCH}.deb 2>/dev/null | xargs -r rm -f +export NFPM_ARCH nfpm pkg --packager deb --target dist/ -DEB_FILE=$(ls dist/mcpctl*.deb 2>/dev/null | head -1) +DEB_FILE=$(ls dist/mcpctl*.deb 2>/dev/null | grep -E "[._]${NFPM_ARCH}[._]" | head -1) echo "==> Built: $DEB_FILE" echo " Size: $(du -h "$DEB_FILE" | cut -f1)" -dpkg-deb --info "$DEB_FILE" 2>/dev/null || true +# dpkg-deb may not be available on RPM-based systems (Fedora) +if command -v dpkg-deb &>/dev/null; then + dpkg-deb --info "$DEB_FILE" 2>/dev/null || true +fi diff --git a/scripts/build-mcpd.sh b/scripts/build-mcpd.sh index ae1b313..08a7f3a 100755 --- a/scripts/build-mcpd.sh +++ b/scripts/build-mcpd.sh @@ -1,5 +1,10 @@ #!/bin/bash -# Build mcpd Docker image and push to Gitea container registry +# Build mcpd Docker image and push to Gitea container registry. +# +# Usage: +# ./build-mcpd.sh [tag] # Build for native arch +# ./build-mcpd.sh [tag] --platform linux/amd64 # Build for specific platform +# ./build-mcpd.sh [tag] --multi-arch # Build for both amd64 and arm64 set -e SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" @@ -16,17 +21,60 @@ REGISTRY="10.0.0.194:3012" IMAGE="mcpd" TAG="${1:-latest}" -echo "==> Building mcpd image..." -podman build -t "$IMAGE:$TAG" -f deploy/Dockerfile.mcpd . +# Parse optional flags +PLATFORM="" +MULTI_ARCH=false +shift 2>/dev/null || true +while [[ $# -gt 0 ]]; do + case "$1" in + --platform) + PLATFORM="$2" + shift 2 + ;; + --multi-arch) + MULTI_ARCH=true + shift + ;; + *) + shift + ;; + esac +done -echo "==> Tagging as $REGISTRY/michal/$IMAGE:$TAG..." -podman tag "$IMAGE:$TAG" "$REGISTRY/michal/$IMAGE:$TAG" +if [ "$MULTI_ARCH" = true ]; then + echo "==> Building multi-arch mcpd image (linux/amd64 + linux/arm64)..." + podman build --platform linux/amd64,linux/arm64 \ + --manifest "$IMAGE:$TAG" -f deploy/Dockerfile.mcpd . -echo "==> Logging in to $REGISTRY..." -podman login --tls-verify=false -u michal -p "$GITEA_TOKEN" "$REGISTRY" + echo "==> Tagging manifest as $REGISTRY/michal/$IMAGE:$TAG..." + podman tag "$IMAGE:$TAG" "$REGISTRY/michal/$IMAGE:$TAG" -echo "==> Pushing to $REGISTRY/michal/$IMAGE:$TAG..." -podman push --tls-verify=false "$REGISTRY/michal/$IMAGE:$TAG" + echo "==> Logging in to $REGISTRY..." + podman login --tls-verify=false -u michal -p "$GITEA_TOKEN" "$REGISTRY" + + echo "==> Pushing manifest to $REGISTRY/michal/$IMAGE:$TAG..." + podman manifest push --tls-verify=false --all \ + "$REGISTRY/michal/$IMAGE:$TAG" "docker://$REGISTRY/michal/$IMAGE:$TAG" +else + PLATFORM_FLAG="" + if [ -n "$PLATFORM" ]; then + PLATFORM_FLAG="--platform $PLATFORM" + echo "==> Building mcpd image for $PLATFORM..." + else + echo "==> Building mcpd image (native arch)..." + fi + + podman build $PLATFORM_FLAG -t "$IMAGE:$TAG" -f deploy/Dockerfile.mcpd . + + echo "==> Tagging as $REGISTRY/michal/$IMAGE:$TAG..." + podman tag "$IMAGE:$TAG" "$REGISTRY/michal/$IMAGE:$TAG" + + echo "==> Logging in to $REGISTRY..." + podman login --tls-verify=false -u michal -p "$GITEA_TOKEN" "$REGISTRY" + + echo "==> Pushing to $REGISTRY/michal/$IMAGE:$TAG..." + podman push --tls-verify=false "$REGISTRY/michal/$IMAGE:$TAG" +fi # Ensure package is linked to the repository source "$SCRIPT_DIR/link-package.sh" diff --git a/scripts/build-rpm.sh b/scripts/build-rpm.sh index 0bfc3c0..b5d9a45 100755 --- a/scripts/build-rpm.sh +++ b/scripts/build-rpm.sh @@ -13,6 +13,12 @@ fi # Ensure tools are on PATH export PATH="$HOME/.npm-global/bin:$HOME/.bun/bin:$HOME/.local/bin:$PATH" +# Architecture detection / cross-compilation support +# MCPCTL_TARGET_ARCH overrides native detection (e.g. "amd64" or "arm64") +source "$SCRIPT_DIR/arch-helper.sh" +resolve_arch "${MCPCTL_TARGET_ARCH:-}" +# Sets: NFPM_ARCH, BUN_TARGET, ARCH_SUFFIX + echo "==> Running unit tests..." pnpm test:run echo "" @@ -23,9 +29,11 @@ pnpm build echo "==> Generating shell completions..." pnpm completions:generate -echo "==> Bundling standalone binaries..." +echo "==> Bundling standalone binaries (target: ${NFPM_ARCH})..." mkdir -p dist -rm -f dist/mcpctl dist/mcpctl-local dist/mcpctl-*.rpm +rm -f "dist/mcpctl${ARCH_SUFFIX}" "dist/mcpctl-local${ARCH_SUFFIX}" +# Only remove RPMs for the target arch (preserve cross-compiled packages) +ls dist/mcpctl-*.${NFPM_ARCH}.rpm 2>/dev/null | xargs -r rm -f # Ink optionally imports react-devtools-core which isn't installed. # Provide a no-op stub so bun can bundle it (it's only invoked when DEV=true). @@ -33,22 +41,32 @@ if [ ! -e node_modules/react-devtools-core ]; then ln -s ../src/cli/stubs/react-devtools-core node_modules/react-devtools-core fi -bun build src/cli/src/index.ts --compile --outfile dist/mcpctl -bun build src/mcplocal/src/main.ts --compile --outfile dist/mcpctl-local +bun build src/cli/src/index.ts --compile ${BUN_TARGET:+--target "$BUN_TARGET"} --outfile "dist/mcpctl${ARCH_SUFFIX}" +bun build src/mcplocal/src/main.ts --compile ${BUN_TARGET:+--target "$BUN_TARGET"} --outfile "dist/mcpctl-local${ARCH_SUFFIX}" -echo "==> Packaging RPM..." +# If cross-compiling, copy arch-suffixed binaries to the names nfpm expects +if [ -n "$ARCH_SUFFIX" ]; then + cp "dist/mcpctl${ARCH_SUFFIX}" dist/mcpctl + cp "dist/mcpctl-local${ARCH_SUFFIX}" dist/mcpctl-local +fi + +echo "==> Packaging RPM (arch: ${NFPM_ARCH})..." +export NFPM_ARCH nfpm pkg --packager rpm --target dist/ -RPM_FILE=$(ls dist/mcpctl-*.rpm 2>/dev/null | head -1) +RPM_FILE=$(ls dist/mcpctl-*.${NFPM_ARCH}.rpm 2>/dev/null | head -1) echo "==> Built: $RPM_FILE" echo " Size: $(du -h "$RPM_FILE" | cut -f1)" -rpm -qpi "$RPM_FILE" +if command -v rpm &>/dev/null; then + rpm -qpi "$RPM_FILE" +fi echo "" -echo "==> Packaging DEB..." -rm -f dist/mcpctl*.deb +echo "==> Packaging DEB (arch: ${NFPM_ARCH})..." +# Only remove DEBs for the target arch +ls dist/mcpctl*_${NFPM_ARCH}.deb 2>/dev/null | xargs -r rm -f nfpm pkg --packager deb --target dist/ -DEB_FILE=$(ls dist/mcpctl*.deb 2>/dev/null | head -1) +DEB_FILE=$(ls dist/mcpctl*_${NFPM_ARCH}.deb 2>/dev/null | head -1) echo "==> Built: $DEB_FILE" echo " Size: $(du -h "$DEB_FILE" | cut -f1)" diff --git a/scripts/publish-deb.sh b/scripts/publish-deb.sh index fa448d4..ec7f9e2 100755 --- a/scripts/publish-deb.sh +++ b/scripts/publish-deb.sh @@ -20,7 +20,16 @@ if [ -z "$GITEA_TOKEN" ]; then exit 1 fi -DEB_FILE=$(ls dist/mcpctl*.deb 2>/dev/null | head -1) +# Architecture detection (respects MCPCTL_TARGET_ARCH) +source "$SCRIPT_DIR/arch-helper.sh" +resolve_arch "${MCPCTL_TARGET_ARCH:-}" + +# Find DEB matching target architecture +DEB_FILE=$(ls dist/mcpctl*.deb 2>/dev/null | grep -E "[._]${NFPM_ARCH}[._]" | head -1) +if [ -z "$DEB_FILE" ]; then + # Fallback: try any deb file + DEB_FILE=$(ls dist/mcpctl*.deb 2>/dev/null | head -1) +fi if [ -z "$DEB_FILE" ]; then echo "Error: No DEB found in dist/. Run scripts/build-deb.sh first." exit 1 diff --git a/scripts/publish-rpm.sh b/scripts/publish-rpm.sh index e61fb5b..0a15196 100755 --- a/scripts/publish-rpm.sh +++ b/scripts/publish-rpm.sh @@ -20,7 +20,16 @@ if [ -z "$GITEA_TOKEN" ]; then exit 1 fi -RPM_FILE=$(ls dist/mcpctl-*.rpm 2>/dev/null | head -1) +# Architecture detection (respects MCPCTL_TARGET_ARCH) +source "$SCRIPT_DIR/arch-helper.sh" +resolve_arch "${MCPCTL_TARGET_ARCH:-}" + +# Find RPM matching target architecture +RPM_FILE=$(ls dist/mcpctl-*.rpm 2>/dev/null | grep -E "[._]${NFPM_ARCH}[._]" | head -1) +if [ -z "$RPM_FILE" ]; then + # Fallback: try any rpm file + RPM_FILE=$(ls dist/mcpctl-*.rpm 2>/dev/null | head -1) +fi if [ -z "$RPM_FILE" ]; then echo "Error: No RPM found in dist/. Run scripts/build-rpm.sh first." exit 1 diff --git a/scripts/release.sh b/scripts/release.sh index a1b3ccb..2e5c8ff 100755 --- a/scripts/release.sh +++ b/scripts/release.sh @@ -1,4 +1,9 @@ #!/bin/bash +# Build, publish, and install mcpctl packages. +# +# Usage: +# ./release.sh # Build + publish for native arch only +# ./release.sh --both-arches # Build + publish for both amd64 and arm64 set -e SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" @@ -10,24 +15,47 @@ if [ -f .env ]; then set -a; source .env; set +a fi +source "$SCRIPT_DIR/arch-helper.sh" +resolve_arch "${MCPCTL_TARGET_ARCH:-}" +NATIVE_ARCH="$NFPM_ARCH" + +BOTH_ARCHES=false +if [[ "${1:-}" == "--both-arches" ]]; then + BOTH_ARCHES=true +fi + echo "=== mcpctl release ===" +echo " Native arch: $NATIVE_ARCH" echo "" -# Build -bash scripts/build-rpm.sh +build_and_publish() { + local arch="$1" + echo "" + echo "=== Building for $arch ===" + MCPCTL_TARGET_ARCH="$arch" bash scripts/build-rpm.sh + echo "" + MCPCTL_TARGET_ARCH="$arch" bash scripts/publish-rpm.sh + MCPCTL_TARGET_ARCH="$arch" bash scripts/publish-deb.sh +} + +if [ "$BOTH_ARCHES" = true ]; then + build_and_publish "amd64" + build_and_publish "arm64" +else + build_and_publish "$NATIVE_ARCH" +fi echo "" -# Publish -bash scripts/publish-rpm.sh -bash scripts/publish-deb.sh - -echo "" - -# Install locally -echo "==> Installing locally..." -RPM_FILE=$(ls dist/mcpctl-*.rpm 2>/dev/null | head -1) -sudo rpm -U --force "$RPM_FILE" +# Install locally for native arch (auto-detect RPM or DEB) +echo "==> Installing locally (${NATIVE_ARCH})..." +if command -v dpkg &>/dev/null && ! command -v dnf &>/dev/null; then + DEB_FILE=$(ls dist/mcpctl*.deb 2>/dev/null | grep -E "[._]${NATIVE_ARCH}[._]" | head -1) + sudo dpkg -i "$DEB_FILE" || sudo apt-get install -f -y +else + RPM_FILE=$(ls dist/mcpctl-*.rpm 2>/dev/null | grep -E "[._]${NATIVE_ARCH}[._]" | head -1) + sudo rpm -U --force "$RPM_FILE" +fi echo "" echo "==> Installed:"