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
8 changes: 6 additions & 2 deletions .github/workflows/build_release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -93,10 +93,14 @@ jobs:
for t in linux-x64 linux-arm64 darwin-x64 darwin-arm64; do
cp "sidecars/anfra-node-$t" internal/sidecar/assets/anfra-node
cp "sidecars/canal-query-$t" internal/sidecar/assets/canal-query
# -s -w strips the host's symbol table + DWARF (Phase 0).
GOOS="${OS[$t]}" GOARCH="${ARCH[$t]}" go build -tags embed_sidecar \
-ldflags "-X github.com/holistics/anfra/internal/meta.Version=$VERSION" \
-ldflags "-s -w -X github.com/holistics/anfra/internal/meta.Version=$VERSION" \
-o "release/anfra-$t" ./cmd/anfra
file "release/anfra-$t" || true
# Transport compression (Phase 1, see compression.md): publish only the
# .gz. The embed stays uncompressed so the binary remains delta-friendly.
gzip -9 "release/anfra-$t" # replaces anfra-$t with anfra-$t.gz
file "release/anfra-$t.gz" || true
done
ls -la release

Expand Down
37 changes: 30 additions & 7 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,14 +1,37 @@
## [](https://github.com/holistics/anfra/compare/anfra-v0.1.0...anfra-v) (2026-07-22)
## [0.3.0](https://github.com/holistics/anfra/compare/anfra-v0.2.0...anfra-v0.3.0) (2026-07-23)

### Build

* bump canal-query 2.13.0 ([63048f3](https://github.com/holistics/anfra/commit/63048f35cdf0021c4fc15677108afc12d0992e82))
* compress download ([25cea57](https://github.com/holistics/anfra/commit/25cea57460cc341ffb5bb8c17305a90322c8507c))
## [0.2.0](https://github.com/holistics/anfra/compare/anfra-v0.1.0...anfra-v0.2.0) (2026-07-22)

### Features

* auto update mechanism ([180d9a2](https://github.com/holistics/anfra/commit/180d9a227ebbaaed1bebde90066587a97559cb13))
* auto update mechanism ([258a94c](https://github.com/holistics/anfra/commit/258a94cf8ef08dccec2cebbae6f699c9224f43ae))

### Build

* install.sh script ([a2c9ed6](https://github.com/holistics/anfra/commit/a2c9ed656a072f24ac08d41a45b205207a287125))
# Changelog
* install.sh script ([24de3d9](https://github.com/holistics/anfra/commit/24de3d98b96c23b458284c23a71f3af2038a3d0f))

## [0.1.0](https://github.com/holistics/anfra/compare/c567bd9d4eb4601ca1480de59d02c363ee6f19cc...anfra-v0.1.0) (2026-07-21)

### Features

* implement serve ([1e2fb63](https://github.com/holistics/anfra/commit/1e2fb63b1634ae7052f5ef6b6bfbec2a1deae04a))
* patch aql limit with truncate_rows ([2fd2a90](https://github.com/holistics/anfra/commit/2fd2a90a9075b8732903c72c8c80bef3821dafa4))
* query command ([c567bd9](https://github.com/holistics/anfra/commit/c567bd9d4eb4601ca1480de59d02c363ee6f19cc))
* remove validate --aql, add arg shorthands ([70bf1e2](https://github.com/holistics/anfra/commit/70bf1e29f05153b9ffab7933e4040d9807502e4c))
* validate command ([fa0ce05](https://github.com/holistics/anfra/commit/fa0ce05db16a01b8b853e03cbc63bd3b3f7628d2))

### Bug Fixes

* proper validation for AQL ([d633c21](https://github.com/holistics/anfra/commit/d633c21bbe94a274d7e8e66f71f67c32f368a132))

### Build

* bump anfra_node 0.0.3 ([c9ecb63](https://github.com/holistics/anfra/commit/c9ecb63527ec6b78779afb4fc82c6b7b985b338f))

### Performance Improvements

All notable changes to anfra are documented here, generated from
[conventional commits](https://www.conventionalcommits.org/) via `pnpm bump`
(or `pnpm changelog`).
* enable canal query connection pool when doing serve ([a9a8f25](https://github.com/holistics/anfra/commit/a9a8f250e7a73ce6fb06c98175fc2fd3ea10cb78))
2 changes: 1 addition & 1 deletion cmd/anfra/update.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ func runUpdate(ctx context.Context, checkOnly bool) error {
return nil
}

fmt.Printf("Downloading %s (~250 MB)...\n", rel.Tag)
fmt.Printf("Downloading %s...\n", rel.Tag)
// Show a progress line only on an interactive terminal; stay silent when
// output is piped/captured (agent, CI).
var progress io.Writer
Expand Down
23 changes: 19 additions & 4 deletions install.sh
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,16 @@ INSTALL_DIR="${ANFRA_INSTALL_DIR:-${HOME}/.anfra/bin}"

err() { echo "anfra-install: $*" >&2; exit 1; }

# --- required tools (fail early with a clear message, not mid-run) ---
command -v curl >/dev/null 2>&1 || err "curl is required but not found"
if command -v gunzip >/dev/null 2>&1; then
gunzip_cmd="gunzip -c"
elif command -v gzip >/dev/null 2>&1; then
gunzip_cmd="gzip -dc"
else
err "gzip/gunzip is required to decompress the download but was not found"
fi

# --- detect platform, mapped to the release asset names (anfra-<os>-<arch>) ---
os="$(uname -s | tr '[:upper:]' '[:lower:]')"
case "$os" in
Expand All @@ -41,7 +51,9 @@ case "$arch" in
*) err "unsupported architecture: $arch" ;;
esac

asset="${BIN_NAME}-${os}-${arch}"
# Release binaries are published gzip-compressed for transport (see the anfra
# compression plan); we gunzip after download.
asset="${BIN_NAME}-${os}-${arch}.gz"

# --- resolve the download URL (avoid the GitHub API + its 60 req/hr limit) ---
# The /releases/latest/download/<asset> and /releases/download/<tag>/<asset>
Expand All @@ -53,13 +65,16 @@ else
url="https://github.com/${REPO}/releases/latest/download/${asset}"
fi

# --- download ---
# --- download + decompress ---
tmp="$(mktemp -d)"
trap 'rm -rf "$tmp"' EXIT
echo "Downloading ${asset} (~250 MB) for ${os}/${arch}..."
if ! curl -fL -o "${tmp}/${BIN_NAME}" "$url"; then
echo "Downloading ${asset} for ${os}/${arch}..."
if ! curl -fL -o "${tmp}/${BIN_NAME}.gz" "$url"; then
err "download failed from ${url} (is the release published for this platform?)"
fi
if ! $gunzip_cmd "${tmp}/${BIN_NAME}.gz" > "${tmp}/${BIN_NAME}"; then
err "failed to decompress ${asset}"
fi

# Log the checksum for the record (TOFU; no verification yet).
if command -v sha256sum >/dev/null 2>&1; then
Expand Down
19 changes: 15 additions & 4 deletions internal/update/update.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
package update

import (
"compress/gzip"
"context"
"encoding/json"
"fmt"
Expand Down Expand Up @@ -111,10 +112,13 @@ func get(ctx context.Context, url, accept string, timeout time.Duration) (*http.

// Latest fetches the newest release and resolves the asset for this platform.
func Latest(ctx context.Context) (*Release, error) {
want, err := assetName()
base, err := assetName()
if err != nil {
return nil, err
}
// Release binaries are published gzip-compressed for transport (see the
// compression plan); Apply decompresses on the way in.
want := base + ".gz"
resp, err := get(ctx, fmt.Sprintf("%s/repos/%s/releases/latest", apiBase, repoSlug), "application/vnd.github+json", lookupTimeout)
if err != nil {
return nil, fmt.Errorf("check latest release: %w", err)
Expand Down Expand Up @@ -179,11 +183,18 @@ func Apply(ctx context.Context, r *Release, progress io.Writer) error {
if resp.StatusCode != http.StatusOK {
return fmt.Errorf("download %s: GitHub returned %s", r.Tag, resp.Status)
}
var body io.Reader = resp.Body
// Progress tracks the compressed bytes actually transferred; gzip.Reader then
// decompresses to the real binary for the self-replace (embed stays uncompressed).
var src io.Reader = resp.Body
if progress != nil {
body = &progressReader{r: resp.Body, total: resp.ContentLength, w: progress}
src = &progressReader{r: resp.Body, total: resp.ContentLength, w: progress}
}
if err := selfupdate.Apply(body, selfupdate.Options{}); err != nil {
gz, err := gzip.NewReader(src)
if err != nil {
return fmt.Errorf("decompress %s: %w", r.Tag, err)
}
defer gz.Close()
if err := selfupdate.Apply(gz, selfupdate.Options{}); err != nil {
if rerr := selfupdate.RollbackError(err); rerr != nil {
return fmt.Errorf("update failed and rollback also failed: %v (rollback: %v)", err, rerr)
}
Expand Down
4 changes: 2 additions & 2 deletions manifest.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
# which triggers build_release.yml to download the pinned sidecars, cross-build,
# and publish. Always bump `version` when changing a pin — otherwise the tag
# already exists and no new release is cut.
version: 0.2.0
version: 0.3.0
sidecars:
anfra_node: anfra-node-v0.0.3 # holistics/holistics-core release tag (anfra_node_build_binaries.yml)
canal_query: query-v2.12.0 # holistics/canal release tag (build_and_release_binaries.yml)
canal_query: query-v2.13.0 # holistics/canal release tag (build_and_release_binaries.yml)
15 changes: 13 additions & 2 deletions scripts/bump.sh
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,20 @@ version="${1:?usage: pnpm bump <version> e.g. pnpm bump 0.2.0}"
# manifest.yml is the single source of truth for the release version.
sed -i.bak -E "s/^version: .*/version: ${version}/" manifest.yml && rm -f manifest.yml.bak

# Prepend the changes since the last anfra-v* tag to the changelog.
# Prepend the changes since the last anfra-v* tag to the changelog. The pending
# release version is passed via a context file (mirrors canal's bump) — otherwise
# conventional-changelog reads it from package.json (which has none) and emits an
# empty "## []" header.
git fetch --tags --quiet
pnpm run changelog
# Pass the pending version via a context file (mirrors canal's bump). It must end
# in .json — conventional-changelog loads -c by file extension.
ctx="/tmp/anfra-bump-context.json"
printf '{ "version": "%s" }\n' "$version" > "$ctx"
pnpm exec conventional-changelog \
-n conventional-changelog.config.mjs \
-c "$ctx" \
-i CHANGELOG.md -s \
-t anfra-v

echo "Bumped manifest.yml -> ${version} and updated CHANGELOG.md."
echo "Review both, commit, and merge to main to cut anfra-v${version}."
Loading