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
1 change: 1 addition & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -69,4 +69,5 @@ jobs:
files: |
daybook_*.tar.gz
checksums.txt
scripts/install.sh
generate_release_notes: true
12 changes: 7 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,20 +25,22 @@ my-vault/
## Installation

### Prebuilt Binaries (Recommended)
You can download prebuilt standalone binaries for your platform from [GitHub Releases](https://github.com/StatIndet/daybook/releases).
Supported platforms: Linux (amd64/arm64) and macOS (Intel/Apple Silicon).
The easiest way to install Daybook is using our release installer. This script will automatically detect your OS and architecture, download the latest prebuilt CLI, verify its checksum, and install it to `~/.local/bin`.

Extract the archive and place the `daybook` executable in your system's `PATH`.
```bash
curl -fsSL https://github.com/StatIndet/daybook/releases/latest/download/install.sh | bash
```
Alternatively, you can manually download the binaries from [GitHub Releases](https://github.com/StatIndet/daybook/releases).

### Build from Source
To build the CLI from source, ensure you have **Go** and **Node.js** (>=24) installed.
Building from source is recommended for development. Ensure you have **Go**, **Node.js** (>=24), and **npm** installed.

```bash
git clone https://github.com/StatIndet/daybook.git
cd daybook
./scripts/install-cli.sh
```
This script installs npm dependencies, builds frontend assets, and installs the `daybook` executable to your Go bin path.
This script installs npm dependencies, builds frontend assets, and installs the `daybook` executable to your Go bin path (`$GOBIN` or `$(go env GOPATH)/bin`).

## CLI Commands

Expand Down
143 changes: 143 additions & 0 deletions scripts/install.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
#!/usr/bin/env bash
set -euo pipefail

# GitHub repository
REPO="StatIndet/daybook"
DOWNLOAD_URL_BASE="https://github.com/${REPO}/releases"

# Default install directory
DAYBOOK_INSTALL_DIR="${DAYBOOK_INSTALL_DIR:-${HOME}/.local/bin}"

# Helpers
abort() {
echo "ERROR: $*" >&2
exit 1
}

# 1. Detect OS & Architecture
OS="$(uname -s)"
ARCH="$(uname -m)"

case "$OS" in
Linux)
OS_NAME="linux"
;;
Darwin)
OS_NAME="darwin"
;;
*)
abort "Unsupported platform: $OS/$ARCH"
;;
esac

case "$ARCH" in
x86_64 | amd64)
ARCH_NAME="amd64"
;;
aarch64 | arm64)
ARCH_NAME="arm64"
;;
*)
abort "Unsupported platform: $OS/$ARCH"
;;
esac

PLATFORM="${OS_NAME}_${ARCH_NAME}"
echo "=> Detected platform: $PLATFORM"

# 2. Check dependencies
if command -v curl >/dev/null 2>&1; then
DOWNLOAD_CMD="curl -fsSL"
elif command -v wget >/dev/null 2>&1; then
DOWNLOAD_CMD="wget -qO-"
else
abort "Neither curl nor wget is available. Please install one of them to download Daybook."
fi

if command -v sha256sum >/dev/null 2>&1; then
SHASUM_CMD="sha256sum"
elif command -v shasum >/dev/null 2>&1; then
SHASUM_CMD="shasum -a 256"
else
abort "Neither sha256sum nor shasum is available. Please install one of them for checksum verification."
fi

if ! command -v tar >/dev/null 2>&1; then
abort "tar is not available."
fi

# 3. Get latest release tag
echo "=> Fetching latest release info..."
API_URL="https://api.github.com/repos/${REPO}/releases/latest"
# Extract tag_name using standard text tools
LATEST_TAG=$($DOWNLOAD_CMD "$API_URL" | grep '"tag_name":' | sed -E 's/.*"tag_name": *"([^"]+)".*/\1/')

if [ -z "$LATEST_TAG" ]; then
abort "Failed to determine the latest release tag from GitHub API."
fi

echo "=> Latest release is $LATEST_TAG"

# 4. Construct file names
ASSET_NAME="daybook_${LATEST_TAG}_${PLATFORM}.tar.gz"
ASSET_URL="${DOWNLOAD_URL_BASE}/download/${LATEST_TAG}/${ASSET_NAME}"
CHECKSUMS_URL="${DOWNLOAD_URL_BASE}/download/${LATEST_TAG}/checksums.txt"

# 5. Create temp dir and download
TMP_DIR="$(mktemp -d)"
trap 'rm -rf "$TMP_DIR"' EXIT INT TERM

echo "=> Downloading $ASSET_NAME..."
$DOWNLOAD_CMD "$ASSET_URL" > "$TMP_DIR/$ASSET_NAME" || abort "Failed to download $ASSET_URL"

echo "=> Downloading checksums.txt..."
$DOWNLOAD_CMD "$CHECKSUMS_URL" > "$TMP_DIR/checksums.txt" || abort "Failed to download checksums.txt"

# 6. Verify checksum
echo "=> Verifying checksum..."
cd "$TMP_DIR"

if ! grep -q "$ASSET_NAME" checksums.txt; then
abort "$ASSET_NAME not found in checksums.txt"
fi

EXPECTED_HASH=$(grep "$ASSET_NAME" checksums.txt | awk '{print $1}')
ACTUAL_HASH=$($SHASUM_CMD "$ASSET_NAME" | awk '{print $1}')

if [ "$EXPECTED_HASH" != "$ACTUAL_HASH" ]; then
abort "Checksum verification failed! Expected: $EXPECTED_HASH, Actual: $ACTUAL_HASH"
fi
echo "=> Checksum verified successfully."

# 7. Extract
echo "=> Extracting archive..."
tar -xzf "$ASSET_NAME" daybook || abort "Failed to extract tar.gz"

if [ ! -f "daybook" ]; then
abort "Extracted archive did not contain 'daybook' binary."
fi

chmod +x daybook

# 8. Install
echo "=> Installing daybook to $DAYBOOK_INSTALL_DIR..."
mkdir -p "$DAYBOOK_INSTALL_DIR" || abort "Failed to create directory: $DAYBOOK_INSTALL_DIR"
cp daybook "$DAYBOOK_INSTALL_DIR/daybook" || abort "Failed to copy daybook to $DAYBOOK_INSTALL_DIR. Check permissions."

# 9. Verify installation
echo "=> Verifying installation..."
"$DAYBOOK_INSTALL_DIR/daybook" --version || abort "Failed to execute daybook after installation."

echo ""
echo "Daybook $LATEST_TAG installed successfully."
echo "Installed to: $DAYBOOK_INSTALL_DIR/daybook"

# 10. PATH Check
if [[ ":$PATH:" != *":$DAYBOOK_INSTALL_DIR:"* ]]; then
echo ""
echo "Daybook was installed successfully, but $DAYBOOK_INSTALL_DIR is not in your PATH."
echo "Add it to your shell PATH before using \`daybook\`:"
echo ""
echo " export PATH=\"\$PATH:$DAYBOOK_INSTALL_DIR\""
echo ""
fi
Loading