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
29 changes: 29 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
# Keep the build context tight: skip everything that doesn't affect
# the Go build. Big wins are .git and the __examples directory.
.git
.github
.vscode
.idea
.DS_Store
*.log
*.tmp

# Example projects — separate go.mod files, not built into the
# server binary.
__examples

# Test artifacts.
*.test
*.out
*.prof
coverage.txt
bench-*.txt

# Local dev helpers.
docker-compose.yml
docker-compose.*.yml
!docker-compose.cluster.yml

# Docs that don't affect the binary.
*.md
docs
59 changes: 59 additions & 0 deletions .github/workflows/cluster.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
---
name: cluster

# Cross-process cluster smoke. Boots the 5-node docker-compose
# stack defined at docker-compose.cluster.yml, waits for every
# node's /healthz to flip to 200, then runs the assertion script
# under scripts/tests/. Catches the class of bugs that unit
# tests miss because they only exercise in-process behavior:
# * config not flowing from HyperCache wrapper to DistMemory
# * seed lists with empty node IDs producing broken rings
# * wire-encoding asymmetries between writer and replica
#
# Container logs are dumped on failure so a CI failure is
# debuggable without re-running locally.

on:
pull_request:
push:
branches: [main]

permissions:
contents: read

jobs:
smoke:
name: 5-node smoke
runs-on: ubuntu-latest
timeout-minutes: 10

steps:
- uses: actions/checkout@v6

- name: Build cluster image
run: |
docker compose -f docker-compose.cluster.yml build

- name: Bring cluster up
run: |
docker compose -f docker-compose.cluster.yml up -d

- name: Wait for cluster /healthz
run: bash scripts/tests/wait-for-cluster.sh

- name: Run cross-node smoke
run: bash scripts/tests/10-test-cluster-api.sh

- name: Dump container logs (on failure)
if: failure()
run: |
for c in hypercache-1 hypercache-2 hypercache-3 hypercache-4 hypercache-5; do
echo "::group::$c"
docker logs --tail 200 "$c" || true
echo "::endgroup::"
done

- name: Tear down
if: always()
run: |
docker compose -f docker-compose.cluster.yml down -v --remove-orphans
2 changes: 1 addition & 1 deletion .github/workflows/gitleaks.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ permissions:
on:
pull_request:
push:
branches: [main]
branches: [ main ]
workflow_dispatch:
schedule:
# run once a day at 4 AM
Expand Down
97 changes: 97 additions & 0 deletions .github/workflows/image.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
---
name: image

# Build (and on the right refs, publish) the hypercache-server
# container image. Three trigger shapes:
# * pull_request — build only, never push (catches Dockerfile
# regressions without polluting the registry).
# * push to main — build + push as `:main` and `:sha-<short>`
# so consumers can pin to either.
# * tag push (v*.*.*) — build + push semver-flavored tags
# (`:v1.2.3`, `:1.2.3`, `:1.2`, `:1`, `:latest`) for stable
# pinning.
# Multi-arch linux/amd64 + linux/arm64 via buildx + qemu so
# operators on Apple Silicon (or k8s nodes on Graviton) get a
# native binary without emulation.

on:
pull_request:
push:
branches: [ main ]
tags: [ "v*.*.*" ]
workflow_dispatch:

permissions:
contents: read
packages: write

env:
REGISTRY: ghcr.io
IMAGE_NAME: ${{ github.repository }}/hypercache-server

jobs:
build:
name: build${{ github.event_name == 'pull_request' && ' (no push)' || ' + push'
}}
runs-on: ubuntu-latest
timeout-minutes: 20

steps:
- uses: actions/checkout@v6

- name: Set up QEMU
uses: docker/setup-qemu-action@v4

- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v4

# Login is gated on non-PR events. Forks running PR workflows
# don't have access to GITHUB_TOKEN with packages:write, and
# we never push from a PR anyway — so skipping the login step
# avoids an avoidable failure on those events.
- name: Log in to GHCR
if: github.event_name != 'pull_request'
uses: docker/login-action@v4.1.0
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}

# docker/metadata-action computes the tag set + OCI labels
# from the triggering ref. The semver patterns only match
# when the ref is a `v*.*.*` tag; on branch/PR pushes they
# produce no tags and the type=ref/type=sha entries take over.
# `:latest` is restricted to semver tag pushes — production
# operators pinning to `:latest` get the highest stable
# release, never an in-flight main commit. The `latest=false`
# flavor disables the metadata-action default behavior that
# would otherwise tag `:latest` on every default-branch push.
- name: Compute tags and labels
id: meta
uses: docker/metadata-action@v6
with:
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
tags: |
type=ref,event=branch
type=ref,event=pr
type=sha,format=short
type=semver,pattern={{version}}
type=semver,pattern={{major}}.{{minor}}
type=semver,pattern={{major}}
type=raw,value=latest,enable=${{ github.ref_type == 'tag' && startsWith(github.ref, 'refs/tags/v') }}
flavor: |
latest=false
- name: Build${{ github.event_name == 'pull_request' && '' || ' + push' }}
uses: docker/build-push-action@v7.1.0
with:
context: .
file: cmd/hypercache-server/Dockerfile
platforms: linux/amd64,linux/arm64
push: ${{ github.event_name != 'pull_request' }}
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
# GHA cache speeds re-builds when only Go source changed
# (the dependency-download layer stays warm).
cache-from: type=gha
cache-to: type=gha,mode=max
3 changes: 0 additions & 3 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,3 @@ tags

### Project ###
.dccache
cmd/
bin/
.github/instructions/instructions.md
15 changes: 15 additions & 0 deletions .gitleaksignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
docker-compose.cluster.yml:curl-auth-header:14
docker-compose.cluster.yml:curl-auth-header:16
docker-compose.cluster.yml:curl-auth-header:17
scripts/tests/10-test-cluster-api.sh:curl-auth-header:6
scripts/tests/10-test-cluster-api.sh:curl-auth-header:13
scripts/tests/10-test-cluster-api.sh:curl-auth-header:19
scripts/tests/10-test-cluster-api.sh:curl-auth-header:26
scripts/tests/10-test-cluster-api.sh:curl-auth-header:32
scripts/tests/10-test-cluster-api.sh:curl-auth-header:36
cmd/hypercache-server/README.md:curl-auth-header:50
cmd/hypercache-server/README.md:curl-auth-header:55
cmd/hypercache-server/README.md:curl-auth-header:59
cmd/hypercache-server/README.md:curl-auth-header:102
cmd/hypercache-server/README.md:curl-auth-header:108
cmd/hypercache-server/README.md:curl-auth-header:112
Loading
Loading