Differing files:
- .github/workflows/release.yml
=== diff: .github/workflows/release.yml ===
--- /home/runner/work/.github/.github/consumer/.github/workflows/release.yml 2026-04-27 07:05:55.310889263 +0000
+++ /home/runner/work/.github/.github/templates-src/templates/go-app/.github/workflows/release.yml 2026-04-27 07:05:52.777054891 +0000
@@ -1,22 +1,15 @@
name: Release
-# Single-build release pipeline for go-app.
+# Atomic-release pipeline for go-app consumers. Delegates the entire
+# release lifecycle (preflight -> binaries -> container -> atomic publish)
+# to the release-go-app.yml reusable orchestrator.
#
-# Go binaries are cross-compiled ONCE by the `binaries` matrix, uploaded
-# to the GitHub Release as user-facing artifacts, and then re-downloaded
-# into `bin/` where the Dockerfile's `COPY bin/<name>-linux-*` stage
-# picks the correct one per TARGETARCH/TARGETVARIANT. No `go build`
-# runs inside Docker.
+# Per-repo customization: usually nothing. Override inputs (e.g.
+# container=false, custom platforms) via the `with:` block below.
#
-# Convention for frontend-embedding repos: ship `bun run build:assets`
-# in package.json; this workflow invokes it before `go build` so assets
-# exist when `go:embed` resolves them. No-op when package.json is
-# absent, so non-frontend repos use this identical workflow unchanged.
-#
-# This file is template-managed — per-repo differences live in the
-# Dockerfile and (optionally) the package.json build:assets script.
-# Naming is derived from github.event.repository.name so the workflow
-# is byte-identical across consumers.
+# This file is template-managed -- naming derives from
+# github.event.repository.name so the workflow is byte-identical
+# across consumers.
on:
push:
@@ -28,112 +21,29 @@
required: true
type: string
-permissions:
- contents: read
+permissions: {}
jobs:
- create-release:
- name: Create GitHub Release
- uses: netresearch/.github/.github/workflows/create-release.yml@main
- permissions:
- contents: write
- with:
- tag: ${{ inputs.tag || github.ref_name }}
-
- binaries:
- name: Build ${{ matrix.target }}
- needs: create-release
- strategy:
- fail-fast: false
- matrix:
- include:
- - { target: linux-386, goos: linux, goarch: "386" }
- - { target: linux-amd64, goos: linux, goarch: amd64 }
- - { target: linux-arm64, goos: linux, goarch: arm64 }
- - { target: linux-armv6, goos: linux, goarch: arm, goarm: "6" }
- - { target: linux-armv7, goos: linux, goarch: arm, goarm: "7" }
- - { target: darwin-amd64, goos: darwin, goarch: amd64 }
- - { target: darwin-arm64, goos: darwin, goarch: arm64 }
- - { target: windows-amd64, goos: windows, goarch: amd64 }
- uses: netresearch/.github/.github/workflows/build-go-attest.yml@main
+ release:
+ uses: netresearch/.github/.github/workflows/release-go-app.yml@main
permissions:
contents: write
+ packages: write
id-token: write
attestations: write
+ security-events: write
with:
- binary-name: ${{ github.event.repository.name }}-${{ matrix.target }}
- # Resolve after checkout (see build-go-attest.yml). `auto` picks
- # `.` when ./main.go exists, else `./cmd/<repo-name>` when that
- # main.go exists, else fails. Keeps this template file byte-
- # identical regardless of whether the consumer uses a root-main
- # or cmd/ layout.
- main-package: auto
- goos: ${{ matrix.goos }}
- goarch: ${{ matrix.goarch }}
- goarm: ${{ matrix.goarm || '' }}
- # Fleet ldflag convention: repos that want to surface release
- # metadata declare `var version, build, buildTime string` in their
- # main package. Each repo decides which to forward into its own
- # version package (ofelia uses main.* directly; ldap-manager
- # forwards into internal/version.*). Empty values are a silent
- # no-op for repos that don't declare the corresponding var.
- # main.buildTime is injected via auto-build-timestamp (below)
- # so it stays populated on workflow_dispatch backfills where
- # github.event.head_commit is absent.
- ldflags: >-
- -s -w
- -X main.version=${{ needs.create-release.outputs.tag }}
- -X main.build=${{ needs.create-release.outputs.sha }}
- auto-build-timestamp: true
- ref: ${{ needs.create-release.outputs.tag }}
- release-tag: ${{ needs.create-release.outputs.tag }}
- sbom: true
- # setup-bun runs unconditionally. `hashFiles()` in the caller's `with:`
- # is evaluated BEFORE the reusable workflow's checkout, so the caller
- # workspace is empty and any guard would have always returned false.
- # The bun install/run commands below are `-f package.json`-gated, so
- # non-frontend repos (ofelia, raybeam) pay only the ~10s Bun install
- # overhead per matrix entry — no actual bun work happens.
+ app-name: ${{ github.event.repository.name }}
+ tag: ${{ inputs.tag || github.ref_name }}
+ # Orchestrator defaults setup-bun=false (matches build-go-attest.yml).
+ # Template explicitly enables it because all current go-app consumers
+ # either use Bun for asset embedding (ldap-manager) or accept the
+ # ~10s per-runner install overhead in exchange for a byte-identical
+ # template across repos. The pre-build-command below is the actual
+ # gate -- non-Bun repos pay only the install cost, no actual bun work.
setup-bun: true
pre-build-command: |
if [ -f package.json ]; then
bun install --frozen-lockfile
bun run build:assets
fi
-
- container:
- name: Build container image
- needs: [create-release, binaries]
- uses: netresearch/.github/.github/workflows/build-container.yml@main
- permissions:
- contents: read
- packages: write
- security-events: write
- id-token: write
- attestations: write
- with:
- image-name: ${{ github.event.repository.name }}
- ref: ${{ needs.create-release.outputs.tag }}
- platforms: "linux/386,linux/amd64,linux/arm/v6,linux/arm/v7,linux/arm64"
- sign: true
- attest: true
- pre-build-command: |
- set -euo pipefail
- mkdir -p bin
- for suffix in linux-386 linux-amd64 linux-arm64 linux-armv6 linux-armv7; do
- gh release download "${{ needs.create-release.outputs.tag }}" \
- --pattern "${{ github.event.repository.name }}-${suffix}" --dir bin
- chmod +x "bin/${{ github.event.repository.name }}-${suffix}"
- done
-
- finalize:
- name: Finalize release (checksums, cosign, notes)
- needs: [create-release, binaries, container]
- uses: netresearch/.github/.github/workflows/finalize-release.yml@main
- permissions:
- contents: write
- id-token: write
- attestations: write
- with:
- tag: ${{ needs.create-release.outputs.tag }}
- image-ref: ghcr.io/${{ github.repository_owner }}/${{ github.event.repository.name }}
Template drift detected
Repo:
netresearch/raybeamTemplate:
go-app(netresearch/.github)Scan date: 2026-04-27T07:05:55Z
Auto-opened by
.github/workflows/drift-scan.yml. Resolve by runningscripts/sync-template.sh go-app netresearch/raybeam, then openingthe generated PR in the consumer repo.
If the drift is intentional, add an entry to
netresearch/raybeam's.github/template.yamlintentional-drift:list and close this issue.Drift output