From 55a4c8d615ef583f02159b2794564c45b6d83700 Mon Sep 17 00:00:00 2001 From: Dhanraj Date: Sun, 24 May 2026 01:41:37 +0530 Subject: [PATCH 1/8] fix(release): update goreleaser to v2 and add hlctl binary --- .goreleaser.yaml | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/.goreleaser.yaml b/.goreleaser.yaml index e4881d9..06bdf8c 100644 --- a/.goreleaser.yaml +++ b/.goreleaser.yaml @@ -15,12 +15,13 @@ before: - go mod tidy # you may remove this if you don't need go generate - go generate ./... - # Run tests before building + # Run unit tests before building - make test - - make test-it builds: - id: hostlink + binary: hostlink + main: . env: - CGO_ENABLED=0 goos: @@ -31,9 +32,24 @@ builds: ldflags: - -s -w -X hostlink/version.Version={{.Version}} + - id: hlctl + binary: hlctl + main: ./cmd/hlctl + env: + - CGO_ENABLED=0 + goos: + - linux + - darwin + - windows + goarch: + - amd64 + - arm64 + ldflags: + - -s -w -X hostlink/version.Version={{.Version}} + archives: - id: hostlink-archive - builds: [hostlink] + ids: [hostlink, hlctl] formats: [tar.gz] name_template: >- {{ .ProjectName }}_ From b04ce09863b25dc603bb7bb74d71766b69532200 Mon Sep 17 00:00:00 2001 From: Dhanraj Date: Sun, 24 May 2026 01:50:10 +0530 Subject: [PATCH 2/8] ci: opt into Node.js 24 for workflows --- .github/workflows/release.yml | 2 ++ .github/workflows/test.yml | 2 ++ 2 files changed, 4 insertions(+) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 6d8a9da..7241a67 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -16,6 +16,8 @@ permissions: jobs: goreleaser: runs-on: ubuntu-latest + env: + FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true steps: - name: Checkout uses: actions/checkout@v4 diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 3ee9c8d..e9f567d 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -7,6 +7,8 @@ on: jobs: test: runs-on: ubuntu-latest + env: + FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true steps: - name: Checkout uses: actions/checkout@v4 From c1feeedad64f2256860e09a79b966acb4a2f872c Mon Sep 17 00:00:00 2001 From: Dhanraj Date: Sun, 24 May 2026 02:18:44 +0530 Subject: [PATCH 3/8] feat(metrics): support HOSTLINK_TRAEFIK_ENDPOINT env var --- .env.example | 3 +++ config/appconf/appconf.go | 9 +++++++++ config/appconf/appconf_test.go | 10 ++++++++++ internal/traefikmetrics/collector.go | 5 ++--- 4 files changed, 24 insertions(+), 3 deletions(-) diff --git a/.env.example b/.env.example index de738c9..92d6b4b 100644 --- a/.env.example +++ b/.env.example @@ -30,3 +30,6 @@ HOSTLINK_STATE_PATH=./.local # Agent registration tokens (for development testing) HOSTLINK_TOKEN_ID=dev-token-id HOSTLINK_TOKEN_KEY=dev-token-key + +# Traefik metrics endpoint (default: http://localhost:8080/metrics) +HOSTLINK_TRAEFIK_ENDPOINT=http://localhost:8080/metrics diff --git a/config/appconf/appconf.go b/config/appconf/appconf.go index 5e6c86b..4cce03d 100644 --- a/config/appconf/appconf.go +++ b/config/appconf/appconf.go @@ -200,6 +200,15 @@ func HeartbeatInterval() time.Duration { return parseDurationClamped("HOSTLINK_HEARTBEAT_INTERVAL", 5*time.Second, 10*time.Millisecond, 5*time.Minute) } +// TraefikEndpoint returns the Traefik metrics endpoint. +// Controlled by HOSTLINK_TRAEFIK_ENDPOINT (default: http://localhost:8080/metrics). +func TraefikEndpoint() string { + if endpoint := strings.TrimSpace(os.Getenv("HOSTLINK_TRAEFIK_ENDPOINT")); endpoint != "" { + return endpoint + } + return "http://localhost:8080/metrics" +} + // UpdateCheckInterval returns the interval between update checks. // Controlled by HOSTLINK_UPDATE_CHECK_INTERVAL (default: 5m, clamped to [1m, 24h]). func UpdateCheckInterval() time.Duration { diff --git a/config/appconf/appconf_test.go b/config/appconf/appconf_test.go index 18b0d32..3fd3f4e 100644 --- a/config/appconf/appconf_test.go +++ b/config/appconf/appconf_test.go @@ -206,6 +206,16 @@ func TestHeartbeatInterval_CustomValue(t *testing.T) { assert.Equal(t, 200*time.Millisecond, HeartbeatInterval()) } +func TestTraefikEndpoint_Default(t *testing.T) { + t.Setenv("HOSTLINK_TRAEFIK_ENDPOINT", "") + assert.Equal(t, "http://localhost:8080/metrics", TraefikEndpoint()) +} + +func TestTraefikEndpoint_CustomValue(t *testing.T) { + t.Setenv("HOSTLINK_TRAEFIK_ENDPOINT", "http://traefik:8082/metrics") + assert.Equal(t, "http://traefik:8082/metrics", TraefikEndpoint()) +} + func TestLocalTaskStorePath_DefaultUnderAgentStatePath(t *testing.T) { stateDir := t.TempDir() t.Setenv("HOSTLINK_STATE_PATH", stateDir) diff --git a/internal/traefikmetrics/collector.go b/internal/traefikmetrics/collector.go index 6380028..16f12f0 100644 --- a/internal/traefikmetrics/collector.go +++ b/internal/traefikmetrics/collector.go @@ -19,11 +19,10 @@ import ( "sync" "time" + "hostlink/config/appconf" domainmetrics "hostlink/domain/metrics" ) -const defaultEndpoint = "http://localhost:8080/metrics" - type Collector interface { Collect(ctx context.Context) ([]ServiceMetricSet, error) } @@ -46,7 +45,7 @@ type traefikCollector struct { } func New() Collector { - return NewWithEndpoint(defaultEndpoint) + return NewWithEndpoint(appconf.TraefikEndpoint()) } func NewWithEndpoint(endpoint string) Collector { From 46087a8fba5f57a7450f80a9c9f28cf9956e4cf3 Mon Sep 17 00:00:00 2001 From: Dhanraj Date: Sun, 24 May 2026 02:23:05 +0530 Subject: [PATCH 4/8] ci: update actions versions and remove NODE24 env var --- .github/workflows/release.yml | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 7241a67..c2dd058 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -16,21 +16,19 @@ permissions: jobs: goreleaser: runs-on: ubuntu-latest - env: - FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true steps: - name: Checkout - uses: actions/checkout@v4 + uses: actions/checkout@v6 with: fetch-depth: 0 - name: Set up Go - uses: actions/setup-go@v5 + uses: actions/setup-go@v6 with: go-version: stable # More assembly might be required: Docker logins, GPG, etc. # It all depends on your needs. - name: Run GoReleaser - uses: goreleaser/goreleaser-action@v6 + uses: goreleaser/goreleaser-action@v7 with: # either 'goreleaser' (default) or 'goreleaser-pro' distribution: goreleaser From e3894ed73e44b35de692c549fac5823881174330 Mon Sep 17 00:00:00 2001 From: Dhanraj Date: Sun, 24 May 2026 02:32:09 +0530 Subject: [PATCH 5/8] ci: use go-version-file in release workflow --- .github/workflows/release.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index c2dd058..495d18c 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -24,7 +24,7 @@ jobs: - name: Set up Go uses: actions/setup-go@v6 with: - go-version: stable + go-version-file: go.mod # More assembly might be required: Docker logins, GPG, etc. # It all depends on your needs. - name: Run GoReleaser From 034f771d7343b1a75a2e87099e742fd52ae6e44a Mon Sep 17 00:00:00 2001 From: Dhanraj Date: Sun, 24 May 2026 02:33:08 +0530 Subject: [PATCH 6/8] ci: remove before hooks from goreleaser to isolate build failures --- .goreleaser.yaml | 9 --------- 1 file changed, 9 deletions(-) diff --git a/.goreleaser.yaml b/.goreleaser.yaml index 06bdf8c..00868ef 100644 --- a/.goreleaser.yaml +++ b/.goreleaser.yaml @@ -9,15 +9,6 @@ version: 2 project_name: hostlink -before: - hooks: - # You may remove this if you don't use go modules. - - go mod tidy - # you may remove this if you don't need go generate - - go generate ./... - # Run unit tests before building - - make test - builds: - id: hostlink binary: hostlink From 69d5bb73d775fcebc011d97dd3aab00db43415fb Mon Sep 17 00:00:00 2001 From: Dhanraj Date: Sun, 24 May 2026 02:40:40 +0530 Subject: [PATCH 7/8] fix(release): split archives by build and fix action versions Split hostlink-archive into separate definitions for hostlink (linux-only with scripts) and hlctl (multi-platform), fixing goreleaser exit code 1 caused by mixed-platform builds in a single archive. Also revert checkout/setup-go to v4/v5 as v6 tags do not exist. Co-Authored-By: Claude Sonnet 4.6 --- .github/workflows/release.yml | 4 ++-- .goreleaser.yaml | 18 ++++++++++++++---- 2 files changed, 16 insertions(+), 6 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 495d18c..d07d376 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -18,11 +18,11 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout - uses: actions/checkout@v6 + uses: actions/checkout@v4 with: fetch-depth: 0 - name: Set up Go - uses: actions/setup-go@v6 + uses: actions/setup-go@v5 with: go-version-file: go.mod # More assembly might be required: Docker logins, GPG, etc. diff --git a/.goreleaser.yaml b/.goreleaser.yaml index 00868ef..009fec3 100644 --- a/.goreleaser.yaml +++ b/.goreleaser.yaml @@ -40,7 +40,7 @@ builds: archives: - id: hostlink-archive - ids: [hostlink, hlctl] + ids: [hostlink] formats: [tar.gz] name_template: >- {{ .ProjectName }}_ @@ -48,14 +48,24 @@ archives: {{- if eq .Arch "amd64" }}x86_64 {{- else }}{{ .Arch }}{{ end }} {{- if .Arm }}v{{ .Arm }}{{ end }} - format_overrides: - - goos: windows - formats: [zip] files: - src: "scripts/**/*" dst: scripts strip_parent: true + - id: hlctl-archive + ids: [hlctl] + formats: [tar.gz] + name_template: >- + hlctl_ + {{- title .Os }}_ + {{- if eq .Arch "amd64" }}x86_64 + {{- else }}{{ .Arch }}{{ end }} + {{- if .Arm }}v{{ .Arm }}{{ end }} + format_overrides: + - goos: windows + formats: [zip] + changelog: sort: asc filters: From df65e76eafc595ef1044bc4a335a1d5107587dea Mon Sep 17 00:00:00 2001 From: Dhanraj Date: Sun, 24 May 2026 17:01:47 +0530 Subject: [PATCH 8/8] Fix metric type name mismatch: traefik.service -> traefik.proxy The Hostlink agent was sending metrics with type "traefik.service" but the Rails control plane expects type "traefik.proxy". Align the metric type constant to match the backend schema so Traefik proxy metrics are properly stored and surfaced in the project metrics endpoint. --- domain/metrics/metrics.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/domain/metrics/metrics.go b/domain/metrics/metrics.go index 1e999ae..66800f0 100644 --- a/domain/metrics/metrics.go +++ b/domain/metrics/metrics.go @@ -11,7 +11,7 @@ const ( MetricTypeMongoDBDatabase = "mongodb.database" MetricTypeRedis = "redis" MetricTypeContainer = "container" - MetricTypeTraefikService = "traefik.service" + MetricTypeTraefikService = "traefik.proxy" ) type MetricPayload struct {