Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 8 additions & 1 deletion .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,12 @@ jobs:
go-version-file: go.mod

- name: Build and package all targets
env:
TAG: ${{ github.event.release.tag_name }}
run: |
mkdir -p dist build
ver="${TAG#v}" # strip a leading "v" if present
ldflags="-s -w -X github.com/php-debugger/installer/internal/version.Version=${ver}"
# Windows-on-ARM runs x64 under emulation, so one Windows build suffices.
for target in linux/amd64 linux/arm64 darwin/amd64 darwin/arm64 windows/amd64; do
goos="${target%/*}"; arch="${target#*/}"
Expand All @@ -31,7 +35,7 @@ jobs:

echo "building $osname/$arch"
CGO_ENABLED=0 GOOS="$goos" GOARCH="$arch" \
go build -trimpath -ldflags "-s -w" -o "build/$bin" .
go build -trimpath -ldflags "$ldflags" -o "build/$bin" .
chmod +x "build/$bin"

# Package into an archive so the executable bit survives download
Expand All @@ -44,6 +48,9 @@ jobs:
fi
rm -f "build/$bin"
done
# Attach the install scripts too, so releases/latest/download/install.sh
# is a stable URL that serves the released version of the script.
cp scripts/install.sh scripts/install.ps1 dist/
ls -la dist

- name: Attach binaries to the release
Expand Down
33 changes: 29 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,28 @@ pulls the **latest release** and auto-detects your OS and architecture.

## Installation

### Install script (recommended)

macOS / Linux:

```bash
curl -fsSL https://github.com/php-debugger/installer/releases/latest/download/install.sh | sh
```

Windows (PowerShell):

```powershell
powershell -c "irm https://github.com/php-debugger/installer/releases/latest/download/install.ps1 | iex"
```

The script detects your OS/arch, downloads the right archive, and installs the
binary (into the current directory by default; set `INSTALL_DIR` to change it, or
`VERSION` to pin a release). Because it fetches with `curl`/`wget` rather than a
browser, the binary is **not quarantined**, so macOS Gatekeeper doesn't block it.

### Download a prebuilt binary

Grab the archive for your platform from the
Alternatively, grab the archive for your platform from the
[Releases page](https://github.com/php-debugger/installer/releases):

| Platform | Asset |
Expand All @@ -20,16 +39,22 @@ Grab the archive for your platform from the
| Linux (arm64) | `php-debugger-linux-arm64.tar.gz` |
| Windows (x64) | `php-debugger-windows-amd64.zip` |

On macOS/Linux, extract **in the terminal** (not by double-clicking in Finder).
Command-line `tar` keeps the executable bit and avoids macOS Gatekeeper flagging
the binary — no `chmod` or "allow anyway" needed:
Extract it (command-line `tar` keeps the executable bit) and put it on your PATH:

```bash
tar -xzf php-debugger-macos-arm64.tar.gz
mv php-debugger /usr/local/bin/ # or ~/.local/bin
php-debugger --help
```

On macOS, a binary downloaded through a **browser** is quarantined, so Gatekeeper
shows "Apple could not verify…". These builds are ad-hoc signed but not notarized,
so clear the quarantine flag once (the install script above avoids this entirely):

```bash
xattr -d com.apple.quarantine ./php-debugger
```

On Windows, unzip the archive and put `php-debugger.exe` somewhere on your PATH.

### Build from source
Expand Down
3 changes: 3 additions & 0 deletions internal/cli/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"fmt"
"os"

"github.com/php-debugger/installer/internal/version"
"github.com/spf13/cobra"
)

Expand All @@ -27,6 +28,7 @@ func newRootCmd() *cobra.Command {
Long: "php-debugger installs the PHP debugger from the php-debugger/php-debugger\n" +
"GitHub releases: either a self-contained PHP interpreter with the debugger\n" +
"compiled in (default), or the debugger extension for an existing PHP.",
Version: version.Version,
SilenceUsage: true,
SilenceErrors: true,
}
Expand All @@ -45,6 +47,7 @@ func newRootCmd() *cobra.Command {
newUninstallCmd(),
newSwitchCmd(),
newResolveCmd(),
newVersionCmd(),
)

return rootCmd
Expand Down
26 changes: 26 additions & 0 deletions internal/cli/version.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package cli

import (
"fmt"
"runtime"

"github.com/php-debugger/installer/internal/platform"
"github.com/php-debugger/installer/internal/version"
"github.com/spf13/cobra"
)

func newVersionCmd() *cobra.Command {
return &cobra.Command{
Use: "version",
Short: "Print the installer version",
Args: cobra.NoArgs,
RunE: func(cmd *cobra.Command, args []string) error {
plat := runtime.GOOS + "/" + runtime.GOARCH
if p, err := platform.Detect(); err == nil {
plat = p.String()
}
fmt.Fprintf(cmd.OutOrStdout(), "php-debugger %s (%s)\n", version.Version, plat)
return nil
},
}
}
8 changes: 8 additions & 0 deletions internal/version/version.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
// Package version holds the installer's build version.
package version

// Version is the installer version. It is "dev" for local builds; release builds
// override it with the release tag via:
//
// -ldflags "-X github.com/php-debugger/installer/internal/version.Version=<tag>"
var Version = "dev"
51 changes: 51 additions & 0 deletions scripts/install.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
<#
.SYNOPSIS
php-debugger installer bootstrap (Windows).

.DESCRIPTION
Downloads the latest php-debugger release for Windows and installs the binary.

Usage:
powershell -c "irm https://github.com/php-debugger/installer/releases/latest/download/install.ps1 | iex"

Environment overrides:
$env:INSTALL_DIR where to place the binary (default: current directory)
#>

$ErrorActionPreference = "Stop"

$Repo = "php-debugger/installer"
$Bin = "php-debugger.exe"
$InstallDir = if ($env:INSTALL_DIR) { $env:INSTALL_DIR } else { (Get-Location).Path }

# Only one Windows build is published (x64); Windows-on-ARM runs it via emulation.
$Asset = "php-debugger-windows-amd64.zip"

# The releases/latest/download URL always resolves to the newest release.
$Url = "https://github.com/$Repo/releases/latest/download/$Asset"
Write-Host "Installing $Bin (latest, windows/amd64)"

$tmp = Join-Path $env:TEMP ("php-debugger-" + [System.Guid]::NewGuid().ToString())
New-Item -ItemType Directory -Path $tmp | Out-Null
try {
$zip = Join-Path $tmp $Asset
Invoke-WebRequest -UseBasicParsing -Uri $Url -OutFile $zip
Expand-Archive -Path $zip -DestinationPath $tmp -Force

$src = Join-Path $tmp $Bin
if (-not (Test-Path $src)) { throw "archive did not contain $Bin" }

New-Item -ItemType Directory -Force -Path $InstallDir | Out-Null
Move-Item -Force $src (Join-Path $InstallDir $Bin)
} finally {
Remove-Item -Recurse -Force $tmp -ErrorAction SilentlyContinue
}

Write-Host ""
Write-Host "Installed to $InstallDir\$Bin"
$onPath = ($env:PATH -split ';') -contains $InstallDir
if ($onPath) {
Write-Host "Run: php-debugger install"
} else {
Write-Host "Add $InstallDir to your PATH, then run 'php-debugger install'."
}
78 changes: 78 additions & 0 deletions scripts/install.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
#!/bin/sh
# php-debugger installer bootstrap (Linux/macOS). Always installs the latest release.
#
# Usage:
# curl -fsSL https://github.com/php-debugger/installer/releases/latest/download/install.sh | sh
# wget -qO- https://github.com/php-debugger/installer/releases/latest/download/install.sh | sh
#
# Environment overrides:
# INSTALL_DIR=/path where to place the binary (default: current directory)
#
# Because the archive is fetched with curl/wget (not a browser), the binary is
# not quarantined, so macOS Gatekeeper does not block it. As a safety net the
# script also clears the quarantine attribute if present.
set -eu

REPO="php-debugger/installer"
BIN="php-debugger"
INSTALL_DIR="${INSTALL_DIR:-$(pwd)}"

info() { printf '%s\n' "$*"; }
fail() { printf 'error: %s\n' "$*" >&2; exit 1; }
have() { command -v "$1" >/dev/null 2>&1; }

download() { # download URL FILE
if have curl; then curl -fsSL "$1" -o "$2"
elif have wget; then wget -q "$1" -O "$2"
else fail "need curl or wget to download"; fi
}

# --- detect OS ---
kernel="$(uname -s)"
case "$kernel" in
Linux) OS="linux" ;;
Darwin) OS="macos" ;;
*) fail "unsupported operating system: $kernel (see the build-from-source instructions)" ;;
esac

# --- detect architecture ---
machine="$(uname -m)"
case "$machine" in
x86_64 | amd64) ARCH="amd64" ;;
arm64 | aarch64) ARCH="arm64" ;;
*) fail "unsupported architecture: $machine" ;;
esac

ASSET="php-debugger-${OS}-${ARCH}.tar.gz"
# The releases/latest/download URL always resolves to the newest release.
URL="https://github.com/$REPO/releases/latest/download/$ASSET"

info "Installing $BIN (latest, $OS/$ARCH)"

# --- download + extract ---
tmp="$(mktemp -d)"
trap 'rm -rf "$tmp"' EXIT INT TERM
download "$URL" "$tmp/$ASSET" || fail "failed to download $URL"
tar -xzf "$tmp/$ASSET" -C "$tmp" || fail "failed to extract $ASSET"
[ -f "$tmp/$BIN" ] || fail "archive did not contain $BIN"

# --- install ---
mkdir -p "$INSTALL_DIR"
mv "$tmp/$BIN" "$INSTALL_DIR/$BIN"
chmod +x "$INSTALL_DIR/$BIN"
# Clear any quarantine attribute so macOS Gatekeeper does not block it.
if [ "$OS" = "macos" ]; then
xattr -d com.apple.quarantine "$INSTALL_DIR/$BIN" 2>/dev/null || true
fi

info ""
info "Installed to $INSTALL_DIR/$BIN"
case ":$PATH:" in
*":$INSTALL_DIR:"*)
info "Run: $BIN install"
;;
*)
info "Add $INSTALL_DIR to your PATH, then run '$BIN install':"
info " export PATH=\"$INSTALL_DIR:\$PATH\""
;;
esac
Loading