oficina / docs Public

Merge branch 'fix/release-version' into main

claude agent, operated by paul@keymail.dev pushed by paul@keymail.dev 9871ba0f776fba35723fdd0d6aa60ef599ebfab3 parent 499d200parent 5986df4
2 files changed, +91 −0
  • cmd/docs/release_test.go +75 −0
  • scripts/build-release.sh +16 −0

CI passed — run details

diff --git a/cmd/docs/release_test.go b/cmd/docs/release_test.go
new file mode 100644
index 0000000..f3d594f
--- /dev/null
+++ b/cmd/docs/release_test.go
@@ -0,0 +1,75 @@
+package main
+
+import (
+ "bytes"
+ "context"
+ "io"
+ "net"
+ "net/http"
+ "os"
+ "os/exec"
+ "path/filepath"
+ "runtime"
+ "strings"
+ "testing"
+ "time"
+)
+
+func TestReleaseBinaryReportsItsSourceCommit(t *testing.T) {
+ root, err := filepath.Abs("../..")
+ if err != nil {
+ t.Fatal(err)
+ }
+ commit, err := exec.Command("git", "-C", root, "rev-parse", "HEAD").Output()
+ if err != nil {
+ t.Fatal(err)
+ }
+ dir := t.TempDir()
+ binary := filepath.Join(dir, "docs")
+ ctx, cancel := context.WithTimeout(context.Background(), 2*time.Minute)
+ defer cancel()
+ build := exec.CommandContext(ctx, "bash", filepath.Join(root, "scripts/build-release.sh"), binary)
+ build.Dir = root
+ build.Env = append(os.Environ(), "GOOS="+runtime.GOOS, "GOARCH="+runtime.GOARCH)
+ if output, err := build.CombinedOutput(); err != nil {
+ t.Fatalf("build: %v\n%s", err, output)
+ }
+ socket := filepath.Join(dir, "docs.sock")
+ var output bytes.Buffer
+ server := exec.CommandContext(ctx, binary, "-env", "development", "-socket", socket, "-db", filepath.Join(dir, "docs.db"))
+ server.Env = append(os.Environ(), "DOCS_ORIGIN=http://localhost", "DOCS_SEED_ADDRESS=", "DOCS_SAMPLE_DOCUMENTS=0")
+ server.Stdout = &output
+ server.Stderr = &output
+ if err := server.Start(); err != nil {
+ t.Fatal(err)
+ }
+ t.Cleanup(func() {
+ _ = server.Process.Kill()
+ _ = server.Wait()
+ })
+ transport := &http.Transport{DialContext: func(ctx context.Context, _, _ string) (net.Conn, error) {
+ return (&net.Dialer{}).DialContext(ctx, "unix", socket)
+ }}
+ defer transport.CloseIdleConnections()
+ client := &http.Client{Transport: transport, Timeout: time.Second}
+ deadline := time.Now().Add(15 * time.Second)
+ for time.Now().Before(deadline) {
+ response, err := client.Get("http://localhost/api/version")
+ if err != nil {
+ time.Sleep(25 * time.Millisecond)
+ continue
+ }
+ body, readErr := io.ReadAll(response.Body)
+ _ = response.Body.Close()
+ if readErr != nil {
+ t.Fatal(readErr)
+ }
+ if response.StatusCode != http.StatusOK || strings.TrimSpace(string(body)) != strings.TrimSpace(string(commit)) {
+ t.Fatalf("version response %d %q; want commit %q", response.StatusCode, body, strings.TrimSpace(string(commit)))
+ }
+ return
+ }
+ _ = server.Process.Kill()
+ _ = server.Wait()
+ t.Fatalf("process did not answer /api/version: %s", output.String())
+}
diff --git a/scripts/build-release.sh b/scripts/build-release.sh
new file mode 100755
index 0000000..36b33aa
--- /dev/null
+++ b/scripts/build-release.sh
@@ -0,0 +1,16 @@
+#!/usr/bin/env bash
+set -euo pipefail
+
+test "$#" -ge 1
+test "$#" -le 2
+docs_output=$(realpath -m -- "$1")
+cd "$(dirname "$0")/.."
+docs_revision=$(git rev-parse --verify "${2:-HEAD}^{commit}")
+docs_source=$(mktemp -d)
+trap 'rm -rf -- "$docs_source"' EXIT
+git archive "$docs_revision" | tar -x -C "$docs_source"
+cd "$docs_source"
+CGO_ENABLED=0 GOOS="${GOOS:-linux}" GOARCH="${GOARCH:-arm64}" \
+ go build -mod=readonly -trimpath \
+ -ldflags "-X github.com/carlosframework/rastrillo.BuildVersion=$docs_revision" \
+ -o "$docs_output" ./cmd/docs