mirror of
https://github.com/hyperdxio/hyperdx
synced 2026-04-21 13:37:15 +00:00
## Summary
Adds `packages/cli` (`@hyperdx/cli`) — a unified CLI for HyperDX that provides an interactive TUI for searching/tailing logs and traces, source map upload (migrated from `hyperdx-js`), and agent-friendly commands for programmatic access.
Ref: HDX-3919
Ref: HDX-3920
### CLI Commands
```
hdx tui -s <url> # Interactive TUI (main command)
hdx sources -s <url> # List sources with ClickHouse schemas
hdx sources -s <url> --json # JSON output for agents / scripts
hdx dashboards -s <url> # List dashboards with tile summaries
hdx dashboards -s <url> --json # JSON output for agents / scripts
hdx query --source "Logs" --sql "SELECT count() FROM default.otel_logs"
hdx upload-sourcemaps -k <key> # Upload source maps (ported from hyperdx-js)
hdx auth login -s <url> # Sign in (interactive or -e/-p flags)
hdx auth status # Show auth status
hdx auth logout # Clear saved session
```
### Key Features
**Interactive TUI (`hdx tui`)**
- Table view with dynamic columns derived from query results (percentage-based widths)
- Follow mode (live tail) enabled by default, auto-pauses when detail panel is open
- Vim-like keybindings: j/k navigation, G/g jump, Ctrl+D/U half-page scroll
- `/` for Lucene search, `s` to edit SELECT clause in `$EDITOR`, `t` to edit time range
- Tab to cycle between sources and saved searches
- `w` to toggle line wrap
**Detail Panel (3 tabs, full-screen with Ctrl+D/U scrolling)**
- **Overview** — Structured view: Top Level Attributes, Log/Span Attributes, Resource Attributes
- **Column Values** — Full `SELECT *` row data with `__hdx_*` aliased columns
- **Trace** — Waterfall chart (port of `DBTraceWaterfallChart` DAG builder) with correlated log events, j/k span navigation, inverse highlight, Event Details section
**Agent-friendly commands**
- `hdx sources --json` — Full source metadata with ClickHouse `CREATE TABLE` DDL, expression mappings, and correlated source IDs. Detailed `--help` describes the JSON schema for LLM consumption. Schema queries run in parallel.
- `hdx dashboards --json` — Dashboard metadata with simplified tile summaries (name, type, source, sql). Resolves source names for human-readable output.
- `hdx query --source <name> --sql <query>` — Raw SQL execution against any source's ClickHouse connection. Supports `--format` for ClickHouse output formats (JSON, JSONEachRow, CSV, etc.).
**Source map upload (`hdx upload-sourcemaps`)**
- Ported from `hyperdx-js/packages/cli` to consolidate on a single `@hyperdx/cli` package
- Authenticates via service account API key (`-k` / `HYPERDX_SERVICE_KEY` env var)
- Globs `.js` and `.js.map` files, handles Next.js route groups
- Uploads to presigned URLs in parallel with retry (3 attempts) and progress
- Modernized: native `fetch` (Node 22+), ESM-compatible, proper TypeScript types
### Architecture
```
packages/cli/
├── src/
│ ├── cli.tsx # Commander CLI: tui, sources, dashboards, query,
│ │ # upload-sourcemaps, auth
│ ├── App.tsx # Ink app shell (login → source picker → EventViewer)
│ ├── sourcemaps.ts # Source map upload logic (ported from hyperdx-js)
│ ├── api/
│ │ ├── client.ts # ApiClient + ProxyClickhouseClient
│ │ └── eventQuery.ts # Query builders (renderChartConfig, raw SQL)
│ ├── components/
│ │ ├── EventViewer/ # Main TUI (9 files)
│ │ │ ├── EventViewer.tsx # Orchestrator (state, hooks, render shell)
│ │ │ ├── types.ts # Shared types & constants
│ │ │ ├── utils.ts # Row formatting functions
│ │ │ ├── SubComponents.tsx # Header, TabBar, SearchBar, Footer, HelpScreen, TableHeader
│ │ │ ├── TableView.tsx # Table rows rendering
│ │ │ ├── DetailPanel.tsx # Detail panel (overview/columns/trace tabs)
│ │ │ ├── useEventData.ts # Data fetching hook
│ │ │ └── useKeybindings.ts # Input handler hook
│ │ ├── TraceWaterfall/ # Trace chart (6 files)
│ │ │ ├── TraceWaterfall.tsx # Orchestrator + render
│ │ │ ├── types.ts # SpanRow, SpanNode, props
│ │ │ ├── utils.ts # Duration/status/bar helpers
│ │ │ ├── buildTree.ts # DAG builder (port of DBTraceWaterfallChart)
│ │ │ └── useTraceData.ts # Data fetching hook
│ │ ├── RowOverview.tsx
│ │ ├── ColumnValues.tsx
│ │ ├── LoginForm.tsx
│ │ └── SourcePicker.tsx
│ ├── shared/ # Ported from packages/app (@source annotated)
│ └── utils/ # Config, editor, log silencing
├── AGENTS.md
├── CONTRIBUTING.md
└── README.md
```
### Tech Stack
- **Ink v6.8.0** (React 19 for terminals) + Commander.js
- **@clickhouse/client** via ProxyClickhouseClient (routes through `/clickhouse-proxy`)
- **@hyperdx/common-utils** for query generation (`renderChartConfig`, `chSqlToAliasMap`)
- **glob v13** for source map file discovery
- **tsup** for bundling (all deps bundled via `noExternal: [/.*/]`, zero runtime deps)
- **Bun 1.3.11** for standalone binary compilation
- Session stored at `~/.config/hyperdx/cli/session.json`
### CI/CD (`release.yml`)
- CLI binaries compiled for macOS ARM64, macOS x64, and Linux x64
- GitHub Release created with download instructions
- Version-change gate: skips release if `cli-v{version}` tag already exists
- `softprops/action-gh-release` pinned to full SHA (v2.6.1) for supply chain safety
- Bun pinned to `1.3.11` for reproducible builds
- npm publishing handled by changesets
### Keybindings
| Key | Action |
|---|---|
| `j/k` | Navigate rows (or spans in Trace tab) |
| `l/Enter` | Expand row detail |
| `h/Esc` | Close detail / blur search |
| `G/g` | Jump to newest/oldest |
| `Ctrl+D/U` | Scroll half-page (table, detail panels, Event Details) |
| `/` | Search (global or detail filter) |
| `Tab` | Cycle sources/searches or detail tabs |
| `s` | Edit SELECT clause in $EDITOR |
| `t` | Edit time range in $EDITOR |
| `f` | Toggle follow mode (live tail) |
| `w` | Toggle line wrap |
| `?` | Help screen |
### Demo
#### Main Search View
<img width="1004" height="1014" alt="image" src="https://github.com/user-attachments/assets/bb6a7f00-38c9-4281-9915-c71b65d852f8" />
#### Event Details Overview
<img width="1003" height="1024" alt="image" src="https://github.com/user-attachments/assets/57025fa5-fddb-452a-9320-93465538d5b2" />
#### Trace Waterfall
<img width="1004" height="1029" alt="image" src="https://github.com/user-attachments/assets/3443c898-ea0d-47f3-acc5-edb7cdd31946" />
666 lines
24 KiB
YAML
666 lines
24 KiB
YAML
name: Release
|
||
on:
|
||
push:
|
||
branches: [main]
|
||
permissions:
|
||
contents: write
|
||
packages: write
|
||
pull-requests: write
|
||
actions: read
|
||
jobs:
|
||
check_changesets:
|
||
name: Check Changesets
|
||
runs-on: ubuntu-24.04
|
||
outputs:
|
||
changeset_outputs_hasChangesets:
|
||
${{ steps.changesets.outputs.hasChangesets }}
|
||
steps:
|
||
- name: Checkout
|
||
uses: actions/checkout@v4
|
||
- name: Setup node
|
||
uses: actions/setup-node@v4
|
||
with:
|
||
node-version-file: '.nvmrc'
|
||
cache-dependency-path: 'yarn.lock'
|
||
cache: 'yarn'
|
||
- name: Install root dependencies
|
||
run: yarn install
|
||
- name: Create Release Pull Request or Publish to npm
|
||
if: always()
|
||
continue-on-error: true
|
||
id: changesets
|
||
uses: changesets/action@v1
|
||
with:
|
||
commit: 'chore(release): bump HyperDX app/package versions'
|
||
title: 'Release HyperDX'
|
||
version: yarn run version
|
||
publish: yarn release
|
||
env:
|
||
YARN_ENABLE_IMMUTABLE_INSTALLS: false
|
||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
|
||
|
||
# ---------------------------------------------------------------------------
|
||
# Check if version already published (skip-if-exists)
|
||
# ---------------------------------------------------------------------------
|
||
check_version:
|
||
name: Check if version exists
|
||
needs: check_changesets
|
||
runs-on: ubuntu-24.04
|
||
if:
|
||
needs.check_changesets.outputs.changeset_outputs_hasChangesets == 'false'
|
||
outputs:
|
||
should_release: ${{ steps.check.outputs.should_release }}
|
||
steps:
|
||
- name: Checkout
|
||
uses: actions/checkout@v4
|
||
- name: Load Environment Variables from .env
|
||
uses: xom9ikk/dotenv@v2
|
||
- name: Login to Docker Hub
|
||
uses: docker/login-action@v3
|
||
with:
|
||
username: ${{ secrets.DOCKER_HUB_USERNAME }}
|
||
password: ${{ secrets.DOCKER_HUB_ACCESS_TOKEN }}
|
||
- name: Check if app image tag already exists
|
||
id: check
|
||
run: |
|
||
TAG_EXISTS=$(docker manifest inspect ${{ env.IMAGE_NAME_DOCKERHUB }}:${{ env.IMAGE_VERSION }}${{ env.IMAGE_VERSION_SUB_TAG }} > /dev/null 2>&1 && echo "true" || echo "false")
|
||
if [ "$TAG_EXISTS" = "true" ]; then
|
||
echo "Tag ${{ env.IMAGE_NAME_DOCKERHUB }}:${{ env.IMAGE_VERSION }}${{ env.IMAGE_VERSION_SUB_TAG }} already exists. Skipping release."
|
||
echo "should_release=false" >> $GITHUB_OUTPUT
|
||
else
|
||
echo "Tag does not exist. Proceeding with release."
|
||
echo "should_release=true" >> $GITHUB_OUTPUT
|
||
fi
|
||
|
||
# ---------------------------------------------------------------------------
|
||
# OTel Collector – build each arch natively, then merge into multi-arch tag
|
||
# ---------------------------------------------------------------------------
|
||
build-otel-collector:
|
||
name: Build OTel Collector (${{ matrix.arch }})
|
||
needs: [check_changesets, check_version]
|
||
if: needs.check_version.outputs.should_release == 'true'
|
||
strategy:
|
||
fail-fast: true
|
||
matrix:
|
||
include:
|
||
- arch: amd64
|
||
platform: linux/amd64
|
||
runner: ubuntu-latest
|
||
- arch: arm64
|
||
platform: linux/arm64
|
||
runner: ubuntu-latest-arm64
|
||
runs-on: ${{ matrix.runner }}
|
||
steps:
|
||
- name: Checkout
|
||
uses: actions/checkout@v4
|
||
- name: Setup Docker Buildx
|
||
uses: docker/setup-buildx-action@v3
|
||
- name: Login to Docker Hub
|
||
uses: docker/login-action@v3
|
||
with:
|
||
username: ${{ secrets.DOCKER_HUB_USERNAME }}
|
||
password: ${{ secrets.DOCKER_HUB_ACCESS_TOKEN }}
|
||
- name: Login to GitHub Container Registry
|
||
uses: docker/login-action@v3
|
||
with:
|
||
registry: ghcr.io
|
||
username: ${{ github.actor }}
|
||
password: ${{ secrets.GITHUB_TOKEN }}
|
||
- name: Load Environment Variables from .env
|
||
uses: xom9ikk/dotenv@v2
|
||
- name: Build and Push
|
||
uses: docker/build-push-action@v6
|
||
with:
|
||
context: .
|
||
file: ./docker/otel-collector/Dockerfile
|
||
platforms: ${{ matrix.platform }}
|
||
target: prod
|
||
tags: |
|
||
${{ env.OTEL_COLLECTOR_IMAGE_NAME_DOCKERHUB }}:${{ env.IMAGE_VERSION }}${{ env.IMAGE_VERSION_SUB_TAG }}-${{ matrix.arch }}
|
||
${{ env.NEXT_OTEL_COLLECTOR_IMAGE_NAME_DOCKERHUB }}:${{ env.IMAGE_VERSION }}${{ env.IMAGE_VERSION_SUB_TAG }}-${{ matrix.arch }}
|
||
push: true
|
||
cache-from: type=gha,scope=otel-collector-${{ matrix.arch }}
|
||
cache-to: type=gha,mode=max,scope=otel-collector-${{ matrix.arch }}
|
||
|
||
publish-otel-collector:
|
||
name: Publish OTel Collector Manifest
|
||
needs: [check_version, build-otel-collector]
|
||
runs-on: ubuntu-latest
|
||
steps:
|
||
- name: Checkout
|
||
uses: actions/checkout@v4
|
||
- name: Load Environment Variables from .env
|
||
uses: xom9ikk/dotenv@v2
|
||
- name: Login to Docker Hub
|
||
uses: docker/login-action@v3
|
||
with:
|
||
username: ${{ secrets.DOCKER_HUB_USERNAME }}
|
||
password: ${{ secrets.DOCKER_HUB_ACCESS_TOKEN }}
|
||
- name: Setup Docker Buildx
|
||
uses: docker/setup-buildx-action@v3
|
||
- name: Create multi-arch manifests
|
||
run: |
|
||
VERSION="${{ env.IMAGE_VERSION }}${{ env.IMAGE_VERSION_SUB_TAG }}"
|
||
MAJOR="${{ env.IMAGE_VERSION }}"
|
||
LATEST="${{ env.IMAGE_LATEST_TAG }}"
|
||
for IMAGE in "${{ env.OTEL_COLLECTOR_IMAGE_NAME_DOCKERHUB }}" "${{ env.NEXT_OTEL_COLLECTOR_IMAGE_NAME_DOCKERHUB }}"; do
|
||
docker buildx imagetools create \
|
||
-t "${IMAGE}:${VERSION}" \
|
||
-t "${IMAGE}:${MAJOR}" \
|
||
-t "${IMAGE}:${LATEST}" \
|
||
"${IMAGE}:${VERSION}-amd64" \
|
||
"${IMAGE}:${VERSION}-arm64"
|
||
done
|
||
|
||
# ---------------------------------------------------------------------------
|
||
# App (fullstack prod) – build each arch natively, then merge
|
||
# ---------------------------------------------------------------------------
|
||
build-app:
|
||
name: Build App (${{ matrix.arch }})
|
||
needs: [check_changesets, check_version]
|
||
if: needs.check_version.outputs.should_release == 'true'
|
||
strategy:
|
||
fail-fast: true
|
||
matrix:
|
||
include:
|
||
- arch: amd64
|
||
platform: linux/amd64
|
||
runner: Large-Runner-x64-32
|
||
- arch: arm64
|
||
platform: linux/arm64
|
||
runner: Large-Runner-ARM64-32
|
||
runs-on: ${{ matrix.runner }}
|
||
steps:
|
||
- name: Checkout
|
||
uses: actions/checkout@v4
|
||
- name: Setup Docker Buildx
|
||
uses: docker/setup-buildx-action@v3
|
||
- name: Login to Docker Hub
|
||
uses: docker/login-action@v3
|
||
with:
|
||
username: ${{ secrets.DOCKER_HUB_USERNAME }}
|
||
password: ${{ secrets.DOCKER_HUB_ACCESS_TOKEN }}
|
||
- name: Login to GitHub Container Registry
|
||
uses: docker/login-action@v3
|
||
with:
|
||
registry: ghcr.io
|
||
username: ${{ github.actor }}
|
||
password: ${{ secrets.GITHUB_TOKEN }}
|
||
- name: Load Environment Variables from .env
|
||
uses: xom9ikk/dotenv@v2
|
||
- name: Build and Push
|
||
uses: docker/build-push-action@v6
|
||
with:
|
||
file: ./docker/hyperdx/Dockerfile
|
||
platforms: ${{ matrix.platform }}
|
||
target: prod
|
||
build-contexts: |
|
||
hyperdx=./docker/hyperdx
|
||
api=./packages/api
|
||
app=./packages/app
|
||
build-args: |
|
||
CODE_VERSION=${{ env.CODE_VERSION }}
|
||
tags: |
|
||
${{ env.IMAGE_NAME_DOCKERHUB }}:${{ env.IMAGE_VERSION }}${{ env.IMAGE_VERSION_SUB_TAG }}-${{ matrix.arch }}
|
||
push: true
|
||
sbom: true
|
||
provenance: true
|
||
cache-from: type=gha,scope=app-${{ matrix.arch }}
|
||
cache-to: type=gha,mode=max,scope=app-${{ matrix.arch }}
|
||
|
||
publish-app:
|
||
name: Publish App Manifest
|
||
needs: [check_version, build-app]
|
||
runs-on: ubuntu-latest
|
||
outputs:
|
||
app_was_pushed: 'true'
|
||
steps:
|
||
- name: Checkout
|
||
uses: actions/checkout@v4
|
||
- name: Load Environment Variables from .env
|
||
uses: xom9ikk/dotenv@v2
|
||
- name: Login to Docker Hub
|
||
uses: docker/login-action@v3
|
||
with:
|
||
username: ${{ secrets.DOCKER_HUB_USERNAME }}
|
||
password: ${{ secrets.DOCKER_HUB_ACCESS_TOKEN }}
|
||
- name: Setup Docker Buildx
|
||
uses: docker/setup-buildx-action@v3
|
||
- name: Create multi-arch manifest
|
||
run: |
|
||
VERSION="${{ env.IMAGE_VERSION }}${{ env.IMAGE_VERSION_SUB_TAG }}"
|
||
MAJOR="${{ env.IMAGE_VERSION }}"
|
||
LATEST="${{ env.IMAGE_LATEST_TAG }}"
|
||
IMAGE="${{ env.IMAGE_NAME_DOCKERHUB }}"
|
||
docker buildx imagetools create \
|
||
-t "${IMAGE}:${VERSION}" \
|
||
-t "${IMAGE}:${MAJOR}" \
|
||
-t "${IMAGE}:${LATEST}" \
|
||
"${IMAGE}:${VERSION}-amd64" \
|
||
"${IMAGE}:${VERSION}-arm64"
|
||
|
||
# ---------------------------------------------------------------------------
|
||
# Local (all-in-one-noauth) – build each arch natively, then merge
|
||
# ---------------------------------------------------------------------------
|
||
build-local:
|
||
name: Build Local (${{ matrix.arch }})
|
||
needs: [check_changesets, check_version]
|
||
if: needs.check_version.outputs.should_release == 'true'
|
||
strategy:
|
||
fail-fast: true
|
||
matrix:
|
||
include:
|
||
- arch: amd64
|
||
platform: linux/amd64
|
||
runner: Large-Runner-x64-32
|
||
- arch: arm64
|
||
platform: linux/arm64
|
||
runner: Large-Runner-ARM64-32
|
||
runs-on: ${{ matrix.runner }}
|
||
steps:
|
||
- name: Checkout
|
||
uses: actions/checkout@v4
|
||
- name: Setup Docker Buildx
|
||
uses: docker/setup-buildx-action@v3
|
||
- name: Login to Docker Hub
|
||
uses: docker/login-action@v3
|
||
with:
|
||
username: ${{ secrets.DOCKER_HUB_USERNAME }}
|
||
password: ${{ secrets.DOCKER_HUB_ACCESS_TOKEN }}
|
||
- name: Login to GitHub Container Registry
|
||
uses: docker/login-action@v3
|
||
with:
|
||
registry: ghcr.io
|
||
username: ${{ github.actor }}
|
||
password: ${{ secrets.GITHUB_TOKEN }}
|
||
- name: Load Environment Variables from .env
|
||
uses: xom9ikk/dotenv@v2
|
||
- name: Build and Push
|
||
uses: docker/build-push-action@v6
|
||
with:
|
||
file: ./docker/hyperdx/Dockerfile
|
||
platforms: ${{ matrix.platform }}
|
||
target: all-in-one-noauth
|
||
build-contexts: |
|
||
clickhouse=./docker/clickhouse
|
||
otel-collector=./docker/otel-collector
|
||
hyperdx=./docker/hyperdx
|
||
api=./packages/api
|
||
app=./packages/app
|
||
build-args: |
|
||
CODE_VERSION=${{ env.CODE_VERSION }}
|
||
tags: |
|
||
${{ env.LOCAL_IMAGE_NAME_DOCKERHUB }}:${{ env.IMAGE_VERSION }}${{ env.IMAGE_VERSION_SUB_TAG }}-${{ matrix.arch }}
|
||
${{ env.NEXT_LOCAL_IMAGE_NAME_DOCKERHUB }}:${{ env.IMAGE_VERSION }}${{ env.IMAGE_VERSION_SUB_TAG }}-${{ matrix.arch }}
|
||
push: true
|
||
sbom: true
|
||
provenance: true
|
||
cache-from: type=gha,scope=local-${{ matrix.arch }}
|
||
cache-to: type=gha,mode=max,scope=local-${{ matrix.arch }}
|
||
|
||
publish-local:
|
||
name: Publish Local Manifest
|
||
needs: [check_version, build-local]
|
||
runs-on: ubuntu-latest
|
||
steps:
|
||
- name: Checkout
|
||
uses: actions/checkout@v4
|
||
- name: Load Environment Variables from .env
|
||
uses: xom9ikk/dotenv@v2
|
||
- name: Login to Docker Hub
|
||
uses: docker/login-action@v3
|
||
with:
|
||
username: ${{ secrets.DOCKER_HUB_USERNAME }}
|
||
password: ${{ secrets.DOCKER_HUB_ACCESS_TOKEN }}
|
||
- name: Setup Docker Buildx
|
||
uses: docker/setup-buildx-action@v3
|
||
- name: Create multi-arch manifests
|
||
run: |
|
||
VERSION="${{ env.IMAGE_VERSION }}${{ env.IMAGE_VERSION_SUB_TAG }}"
|
||
MAJOR="${{ env.IMAGE_VERSION }}"
|
||
LATEST="${{ env.IMAGE_LATEST_TAG }}"
|
||
for IMAGE in "${{ env.LOCAL_IMAGE_NAME_DOCKERHUB }}" "${{ env.NEXT_LOCAL_IMAGE_NAME_DOCKERHUB }}"; do
|
||
docker buildx imagetools create \
|
||
-t "${IMAGE}:${VERSION}" \
|
||
-t "${IMAGE}:${MAJOR}" \
|
||
-t "${IMAGE}:${LATEST}" \
|
||
"${IMAGE}:${VERSION}-amd64" \
|
||
"${IMAGE}:${VERSION}-arm64"
|
||
done
|
||
|
||
# ---------------------------------------------------------------------------
|
||
# All-in-One (all-in-one-auth) – build each arch natively, then merge
|
||
# ---------------------------------------------------------------------------
|
||
build-all-in-one:
|
||
name: Build All-in-One (${{ matrix.arch }})
|
||
needs: [check_changesets, check_version]
|
||
if: needs.check_version.outputs.should_release == 'true'
|
||
strategy:
|
||
fail-fast: true
|
||
matrix:
|
||
include:
|
||
- arch: amd64
|
||
platform: linux/amd64
|
||
runner: Large-Runner-x64-32
|
||
- arch: arm64
|
||
platform: linux/arm64
|
||
runner: Large-Runner-ARM64-32
|
||
runs-on: ${{ matrix.runner }}
|
||
steps:
|
||
- name: Checkout
|
||
uses: actions/checkout@v4
|
||
- name: Setup Docker Buildx
|
||
uses: docker/setup-buildx-action@v3
|
||
- name: Login to Docker Hub
|
||
uses: docker/login-action@v3
|
||
with:
|
||
username: ${{ secrets.DOCKER_HUB_USERNAME }}
|
||
password: ${{ secrets.DOCKER_HUB_ACCESS_TOKEN }}
|
||
- name: Login to GitHub Container Registry
|
||
uses: docker/login-action@v3
|
||
with:
|
||
registry: ghcr.io
|
||
username: ${{ github.actor }}
|
||
password: ${{ secrets.GITHUB_TOKEN }}
|
||
- name: Load Environment Variables from .env
|
||
uses: xom9ikk/dotenv@v2
|
||
- name: Build and Push
|
||
uses: docker/build-push-action@v6
|
||
with:
|
||
file: ./docker/hyperdx/Dockerfile
|
||
platforms: ${{ matrix.platform }}
|
||
target: all-in-one-auth
|
||
build-contexts: |
|
||
clickhouse=./docker/clickhouse
|
||
otel-collector=./docker/otel-collector
|
||
hyperdx=./docker/hyperdx
|
||
api=./packages/api
|
||
app=./packages/app
|
||
build-args: |
|
||
CODE_VERSION=${{ env.CODE_VERSION }}
|
||
tags: |
|
||
${{ env.ALL_IN_ONE_IMAGE_NAME_DOCKERHUB }}:${{ env.IMAGE_VERSION }}${{ env.IMAGE_VERSION_SUB_TAG }}-${{ matrix.arch }}
|
||
${{ env.NEXT_ALL_IN_ONE_IMAGE_NAME_DOCKERHUB }}:${{ env.IMAGE_VERSION }}${{ env.IMAGE_VERSION_SUB_TAG }}-${{ matrix.arch }}
|
||
push: true
|
||
sbom: true
|
||
provenance: true
|
||
cache-from: type=gha,scope=all-in-one-${{ matrix.arch }}
|
||
cache-to: type=gha,mode=max,scope=all-in-one-${{ matrix.arch }}
|
||
|
||
publish-all-in-one:
|
||
name: Publish All-in-One Manifest
|
||
needs: [check_version, build-all-in-one]
|
||
runs-on: ubuntu-latest
|
||
steps:
|
||
- name: Checkout
|
||
uses: actions/checkout@v4
|
||
- name: Load Environment Variables from .env
|
||
uses: xom9ikk/dotenv@v2
|
||
- name: Login to Docker Hub
|
||
uses: docker/login-action@v3
|
||
with:
|
||
username: ${{ secrets.DOCKER_HUB_USERNAME }}
|
||
password: ${{ secrets.DOCKER_HUB_ACCESS_TOKEN }}
|
||
- name: Setup Docker Buildx
|
||
uses: docker/setup-buildx-action@v3
|
||
- name: Create multi-arch manifests
|
||
run: |
|
||
VERSION="${{ env.IMAGE_VERSION }}${{ env.IMAGE_VERSION_SUB_TAG }}"
|
||
MAJOR="${{ env.IMAGE_VERSION }}"
|
||
LATEST="${{ env.IMAGE_LATEST_TAG }}"
|
||
for IMAGE in "${{ env.ALL_IN_ONE_IMAGE_NAME_DOCKERHUB }}" "${{ env.NEXT_ALL_IN_ONE_IMAGE_NAME_DOCKERHUB }}"; do
|
||
docker buildx imagetools create \
|
||
-t "${IMAGE}:${VERSION}" \
|
||
-t "${IMAGE}:${MAJOR}" \
|
||
-t "${IMAGE}:${LATEST}" \
|
||
"${IMAGE}:${VERSION}-amd64" \
|
||
"${IMAGE}:${VERSION}-arm64"
|
||
done
|
||
|
||
# ---------------------------------------------------------------------------
|
||
# CLI – compile standalone binaries and upload as GitHub Release assets
|
||
# npm publishing is handled by changesets in the check_changesets job above.
|
||
# This job only compiles platform-specific binaries and creates a GH Release.
|
||
# ---------------------------------------------------------------------------
|
||
release-cli:
|
||
name: Release CLI Binaries
|
||
needs: [check_changesets, check_version]
|
||
if: needs.check_version.outputs.should_release == 'true'
|
||
runs-on: ubuntu-24.04
|
||
steps:
|
||
- name: Checkout
|
||
uses: actions/checkout@v4
|
||
- name: Setup node
|
||
uses: actions/setup-node@v4
|
||
with:
|
||
node-version-file: '.nvmrc'
|
||
cache-dependency-path: 'yarn.lock'
|
||
cache: 'yarn'
|
||
- name: Setup Bun
|
||
uses: oven-sh/setup-bun@v2
|
||
with:
|
||
bun-version: '1.3.11'
|
||
- name: Install dependencies
|
||
run: yarn install
|
||
- name: Get CLI version
|
||
id: cli_version
|
||
run: |
|
||
CLI_VERSION=$(node -p "require('./packages/cli/package.json').version")
|
||
echo "version=${CLI_VERSION}" >> $GITHUB_OUTPUT
|
||
echo "CLI version: ${CLI_VERSION}"
|
||
- name: Check if CLI release already exists
|
||
id: check_cli_release
|
||
env:
|
||
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||
run: |
|
||
if gh release view "cli-v${{ steps.cli_version.outputs.version }}" > /dev/null 2>&1; then
|
||
echo "Release cli-v${{ steps.cli_version.outputs.version }} already exists. Skipping."
|
||
echo "exists=true" >> $GITHUB_OUTPUT
|
||
else
|
||
echo "Release does not exist. Proceeding."
|
||
echo "exists=false" >> $GITHUB_OUTPUT
|
||
fi
|
||
- name: Compile CLI binaries
|
||
if: steps.check_cli_release.outputs.exists == 'false'
|
||
working-directory: packages/cli
|
||
run: |
|
||
yarn compile:linux
|
||
yarn compile:macos
|
||
yarn compile:macos-x64
|
||
- name: Create GitHub Release
|
||
if: steps.check_cli_release.outputs.exists == 'false'
|
||
uses: softprops/action-gh-release@153bb8e04406b158c6c84fc1615b65b24149a1fe # v2.6.1
|
||
with:
|
||
tag_name: cli-v${{ steps.cli_version.outputs.version }}
|
||
name: '@hyperdx/cli v${{ steps.cli_version.outputs.version }}'
|
||
body: |
|
||
## @hyperdx/cli v${{ steps.cli_version.outputs.version }}
|
||
|
||
### Installation
|
||
|
||
**npm (recommended):**
|
||
```bash
|
||
npm install -g @hyperdx/cli
|
||
```
|
||
|
||
**Or run directly with npx:**
|
||
```bash
|
||
npx @hyperdx/cli tui -s <your-hyperdx-api-url>
|
||
```
|
||
|
||
**Manual download (standalone binary, no Node.js required):**
|
||
```bash
|
||
# macOS Apple Silicon
|
||
curl -L https://github.com/hyperdxio/hyperdx/releases/download/cli-v${{ steps.cli_version.outputs.version }}/hdx-darwin-arm64 -o hdx
|
||
# macOS Intel
|
||
curl -L https://github.com/hyperdxio/hyperdx/releases/download/cli-v${{ steps.cli_version.outputs.version }}/hdx-darwin-x64 -o hdx
|
||
# Linux x64
|
||
curl -L https://github.com/hyperdxio/hyperdx/releases/download/cli-v${{ steps.cli_version.outputs.version }}/hdx-linux-x64 -o hdx
|
||
|
||
chmod +x hdx && sudo mv hdx /usr/local/bin/
|
||
```
|
||
|
||
### Usage
|
||
|
||
```bash
|
||
hdx auth login -s <your-hyperdx-api-url>
|
||
hdx tui
|
||
```
|
||
draft: false
|
||
prerelease: false
|
||
files: |
|
||
packages/cli/dist/hdx-linux-x64
|
||
packages/cli/dist/hdx-darwin-arm64
|
||
packages/cli/dist/hdx-darwin-x64
|
||
env:
|
||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||
|
||
# ---------------------------------------------------------------------------
|
||
# Downstream notifications
|
||
# ---------------------------------------------------------------------------
|
||
notify_helm_charts:
|
||
name: Notify Helm-Charts Downstream
|
||
needs:
|
||
[
|
||
check_changesets,
|
||
publish-app,
|
||
publish-otel-collector,
|
||
publish-local,
|
||
publish-all-in-one,
|
||
]
|
||
runs-on: ubuntu-24.04
|
||
if: |
|
||
needs.check_changesets.outputs.changeset_outputs_hasChangesets == 'false' &&
|
||
needs.publish-app.outputs.app_was_pushed == 'true'
|
||
steps:
|
||
- name: Checkout
|
||
uses: actions/checkout@v4
|
||
- name: Load Environment Variables from .env
|
||
uses: xom9ikk/dotenv@v2
|
||
- name: Notify Helm-Charts Downstream
|
||
uses: actions/github-script@v7
|
||
continue-on-error: true
|
||
env:
|
||
TAG: ${{ env.IMAGE_VERSION }}${{ env.IMAGE_VERSION_SUB_TAG }}
|
||
with:
|
||
github-token: ${{ secrets.CH_BOT_PAT }}
|
||
script: |
|
||
const { TAG } = process.env;
|
||
const result = await github.rest.actions.createWorkflowDispatch({
|
||
owner: 'ClickHouse',
|
||
repo: 'ClickStack-helm-charts',
|
||
workflow_id: '${{ secrets.DOWNSTREAM_HC_WORKFLOW_ID }}',
|
||
ref: 'main',
|
||
inputs: {
|
||
tag: TAG
|
||
}
|
||
});
|
||
|
||
notify_ch:
|
||
name: Notify CH Downstream
|
||
needs:
|
||
[
|
||
check_changesets,
|
||
publish-app,
|
||
publish-otel-collector,
|
||
publish-local,
|
||
publish-all-in-one,
|
||
]
|
||
runs-on: ubuntu-24.04
|
||
# Temporarily disabled:
|
||
if: false
|
||
# if: |
|
||
# needs.check_changesets.outputs.changeset_outputs_hasChangesets == 'false' &&
|
||
# needs.publish-app.outputs.app_was_pushed == 'true'
|
||
steps:
|
||
- name: Checkout
|
||
uses: actions/checkout@v4
|
||
- name: Load Environment Variables from .env
|
||
uses: xom9ikk/dotenv@v2
|
||
- name: Get Downstream App Installation Token
|
||
id: auth
|
||
uses: actions/create-github-app-token@v2
|
||
with:
|
||
app-id: ${{ secrets.DOWNSTREAM_CH_APP_ID }}
|
||
private-key: ${{ secrets.DOWNSTREAM_CH_APP_PRIVATE_KEY }}
|
||
owner: ${{ secrets.DOWNSTREAM_CH_OWNER }}
|
||
- name: Notify CH Downstream
|
||
uses: actions/github-script@v7
|
||
continue-on-error: true
|
||
env:
|
||
TAG: ${{ env.IMAGE_VERSION }}${{ env.IMAGE_VERSION_SUB_TAG }}
|
||
with:
|
||
github-token: ${{ steps.auth.outputs.token }}
|
||
script: |
|
||
const { TAG } = process.env;
|
||
const result = await github.rest.actions.createWorkflowDispatch({
|
||
owner: '${{ secrets.DOWNSTREAM_CH_OWNER }}',
|
||
repo: '${{ secrets.DOWNSTREAM_DP_REPO }}',
|
||
workflow_id: '${{ secrets.DOWNSTREAM_DP_WORKFLOW_ID }}',
|
||
ref: 'main',
|
||
inputs: {
|
||
tag: TAG
|
||
}
|
||
});
|
||
|
||
notify_clickhouse_clickstack:
|
||
needs:
|
||
[
|
||
check_changesets,
|
||
publish-app,
|
||
publish-otel-collector,
|
||
publish-local,
|
||
publish-all-in-one,
|
||
]
|
||
if: needs.publish-app.outputs.app_was_pushed == 'true'
|
||
timeout-minutes: 5
|
||
runs-on: ubuntu-24.04
|
||
steps:
|
||
- name: Checkout
|
||
uses: actions/checkout@v4
|
||
- name: Load Environment Variables from .env
|
||
uses: xom9ikk/dotenv@v2
|
||
- name: Notify ClickHouse/clickhouse-clickstack Downstream
|
||
uses: actions/github-script@v7
|
||
continue-on-error: true
|
||
env:
|
||
TAG: ${{ env.IMAGE_VERSION }}${{ env.IMAGE_VERSION_SUB_TAG }}
|
||
with:
|
||
github-token: ${{ secrets.CH_BOT_PAT }}
|
||
script: |
|
||
const { TAG } = process.env;
|
||
const result = await github.rest.actions.createWorkflowDispatch({
|
||
owner: 'ClickHouse',
|
||
repo: 'clickhouse-clickstack',
|
||
workflow_id: 'sync-hyperdx.yml',
|
||
ref: 'main',
|
||
inputs: {
|
||
tag: TAG,
|
||
}
|
||
});
|
||
|
||
otel-cicd-action:
|
||
if: always()
|
||
name: OpenTelemetry Export Trace
|
||
runs-on: ubuntu-latest
|
||
needs:
|
||
[
|
||
check_changesets,
|
||
publish-app,
|
||
publish-otel-collector,
|
||
publish-local,
|
||
publish-all-in-one,
|
||
release-cli,
|
||
notify_helm_charts,
|
||
notify_ch,
|
||
notify_clickhouse_clickstack,
|
||
]
|
||
steps:
|
||
- name: Export workflow
|
||
uses: corentinmusard/otel-cicd-action@v4
|
||
with:
|
||
otlpEndpoint: ${{ secrets.OTLP_ENDPOINT }}/v1/traces
|
||
otlpHeaders: ${{ secrets.OTLP_HEADERS }}
|
||
otelServiceName: 'release-hyperdx-oss-workflow'
|
||
githubToken: ${{ secrets.GITHUB_TOKEN }}
|