build: Release-Pipeline (scripts/release.sh + Gitea-Workflow) und flake.nix
- scripts/release.sh baut die sechs Targets (linux/darwin/windows × amd64/arm64) statisch mit CGO_ENABLED=0, -trimpath, Version und Commit per ldflags, und schreibt checksums.txt. Asset-Vertrag für das Fleet- Rollout: talk_<os>_<arch>[.exe]. Bewusst ohne GoReleaser — dasselbe Artefakt lokal, in CI und unter nix, ohne zusätzliches Werkzeug. - .gitea/workflows/release.yml: bei Tag v* Tests, Build, Gitea-Release mit Assets (actions/gitea-release-action, Repo-Token). - flake.nix: Paket (buildGoModule, ein Binary), App, Overlay, devShell, Formatter. Linux-Wrapper legt alsa-lib in den LD_LIBRARY_PATH (oto lädt ALSA per dlopen, spricht PulseAudio/PipeWire aber direkt in Go) und espeak-ng/libnotify in den PATH. Verifiziert: nix build .#talk, nix flake check, Snapshot-Build aller sechs Targets. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
1 parent
9e2aa506a6
commit
423377bade
3 files changed
+146
No files matched your search
@@ -0,0 +1,40 @@
|
||||
# Release-Matrix: bei Tag v* → Tests → Artefakte für alle Plattformen →
|
||||
# Gitea-Release mit Assets talk_<os>_<arch>[.exe] + checksums.txt.
|
||||
name: release
|
||||
|
||||
on:
|
||||
push:
|
||||
tags:
|
||||
- "v*"
|
||||
|
||||
jobs:
|
||||
release:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0 # git describe braucht die Tags
|
||||
- name: Go einrichten
|
||||
uses: actions/setup-go@v5
|
||||
with:
|
||||
go-version-file: go.mod
|
||||
- name: Tests
|
||||
run: go vet ./... && go test ./...
|
||||
- name: Artefakte bauen
|
||||
run: scripts/release.sh "${{ github.ref_name }}"
|
||||
- name: Gitea-Release anlegen und Assets hochladen
|
||||
uses: https://gitea.com/actions/gitea-release-action@v1
|
||||
with:
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
tag_name: ${{ github.ref_name }}
|
||||
name: talk ${{ github.ref_name }}
|
||||
body: |
|
||||
Statische Binaries (CGO_ENABLED=0), Prüfsummen in `checksums.txt`.
|
||||
|
||||
Installation: passendes `talk_<os>_<arch>` laden, Prüfsumme vergleichen,
|
||||
als `talk` in den PATH legen, `talk doctor`. Der Daemon startet beim ersten
|
||||
Sprechbefehl von selbst.
|
||||
files: |-
|
||||
dist/talk_*
|
||||
dist/checksums.txt
|
||||
@@ -0,0 +1,70 @@
|
||||
{
|
||||
# talk — Sprach-Ausgaben für Skripte und KI-Agenten.
|
||||
#
|
||||
# Nutzung in einer NixOS-/Home-Manager-Konfiguration:
|
||||
# inputs.talk.url = "git+https://code.m3ta.dev/m3tam3re/talk";
|
||||
# environment.systemPackages = [ inputs.talk.packages.${system}.talk ];
|
||||
# oder als Overlay: nixpkgs.overlays = [ inputs.talk.overlays.default ];
|
||||
#
|
||||
# Dieses Flake ersetzt langfristig m3ta-nixpkgs talk/crunch (bash + mpv).
|
||||
description = "talk — Voice-Notifications für Skripte und KI-Agenten (ein Binary, Daemon mit Queue)";
|
||||
|
||||
inputs.nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
|
||||
|
||||
outputs = { self, nixpkgs }:
|
||||
let
|
||||
systems = [ "x86_64-linux" "aarch64-linux" "x86_64-darwin" "aarch64-darwin" ];
|
||||
forAll = f: nixpkgs.lib.genAttrs systems (system: f nixpkgs.legacyPackages.${system});
|
||||
version = if self ? shortRev then "0.0.0-${self.shortRev}" else "0.0.0-dirty";
|
||||
mkTalk = pkgs: pkgs.buildGoModule {
|
||||
pname = "talk";
|
||||
inherit version;
|
||||
src = self;
|
||||
subPackages = [ "cmd/talk" ];
|
||||
# Nach Änderungen an go.mod/go.sum neu setzen: `nix build` nennt den
|
||||
# erwarteten Hash.
|
||||
vendorHash = "sha256-CbF3juTA7V05hh1ElKKACddsCn4bIPeLZxsz2EZxs9I=";
|
||||
env.CGO_ENABLED = 0;
|
||||
ldflags = [ "-s" "-w" "-X" "main.version=${version}" "-X" "main.commit=${self.shortRev or "dirty"}" ];
|
||||
# Prozessgrenzen-Tests starten Daemons und binden Ports — nicht in der Sandbox.
|
||||
doCheck = false;
|
||||
# Audio: oto spricht PulseAudio/PipeWire direkt (reines Go) und fällt auf
|
||||
# ALSA zurück, das es zur Laufzeit per dlopen lädt — auf NixOS nur
|
||||
# auffindbar, wenn wir es in den Pfad legen. OS-Stimme: espeak-ng.
|
||||
nativeBuildInputs = pkgs.lib.optionals pkgs.stdenv.isLinux [ pkgs.makeWrapper ];
|
||||
postInstall = pkgs.lib.optionalString pkgs.stdenv.isLinux ''
|
||||
wrapProgram $out/bin/talk \
|
||||
--prefix LD_LIBRARY_PATH : ${pkgs.lib.makeLibraryPath [ pkgs.alsa-lib ]} \
|
||||
--prefix PATH : ${pkgs.lib.makeBinPath [ pkgs.espeak-ng pkgs.libnotify ]}
|
||||
'';
|
||||
meta = with pkgs.lib; {
|
||||
description = "Voice-Notifications für Skripte und KI-Agenten";
|
||||
homepage = "https://code.m3ta.dev/m3tam3re/talk";
|
||||
license = licenses.mit;
|
||||
mainProgram = "talk";
|
||||
platforms = platforms.unix;
|
||||
};
|
||||
};
|
||||
in
|
||||
{
|
||||
packages = forAll (pkgs: rec {
|
||||
talk = mkTalk pkgs;
|
||||
default = talk;
|
||||
});
|
||||
|
||||
apps = forAll (pkgs: rec {
|
||||
talk = { type = "app"; program = "${mkTalk pkgs}/bin/talk"; };
|
||||
default = talk;
|
||||
});
|
||||
|
||||
overlays.default = final: prev: { talk = mkTalk final; };
|
||||
|
||||
devShells = forAll (pkgs: {
|
||||
default = pkgs.mkShell {
|
||||
packages = [ pkgs.go pkgs.gopls pkgs.gotools pkgs.espeak-ng pkgs.libnotify ];
|
||||
};
|
||||
});
|
||||
|
||||
formatter = forAll (pkgs: pkgs.nixfmt-rfc-style);
|
||||
};
|
||||
}
|
||||
Executable
+36
@@ -0,0 +1,36 @@
|
||||
#!/usr/bin/env sh
|
||||
# Baut die Release-Artefakte von talk für alle Zielplattformen — reproduzierbar
|
||||
# mit nichts als dem Go-Toolchain (kein GoReleaser nötig; so läuft derselbe
|
||||
# Schritt lokal, in Gitea Actions und in nix identisch).
|
||||
#
|
||||
# Asset-Vertrag (agent-lib-Muster, Fleet-Rollout pinnt darauf):
|
||||
# dist/talk_<os>_<arch>[.exe] statisches Binary, CGO_ENABLED=0
|
||||
# dist/checksums.txt sha256 je Asset (sha256sum-Format)
|
||||
#
|
||||
# Aufruf: scripts/release.sh [VERSION] (Default: git describe, sonst "dev")
|
||||
# Env: TARGETS="linux/amd64 …" überschreibt die Matrix.
|
||||
set -eu
|
||||
|
||||
cd "$(dirname "$0")/.."
|
||||
VERSION="${1:-$(git describe --tags --always --dirty 2>/dev/null || echo dev)}"
|
||||
VERSION="${VERSION#v}"
|
||||
COMMIT="$(git rev-parse --short HEAD 2>/dev/null || echo unknown)"
|
||||
TARGETS="${TARGETS:-linux/amd64 linux/arm64 darwin/amd64 darwin/arm64 windows/amd64 windows/arm64}"
|
||||
DIST=dist
|
||||
|
||||
rm -rf "$DIST"
|
||||
mkdir -p "$DIST"
|
||||
for target in $TARGETS; do
|
||||
os="${target%/*}"
|
||||
arch="${target#*/}"
|
||||
out="$DIST/talk_${os}_${arch}"
|
||||
[ "$os" = windows ] && out="$out.exe"
|
||||
echo "build $out"
|
||||
CGO_ENABLED=0 GOOS="$os" GOARCH="$arch" go build -trimpath \
|
||||
-ldflags "-s -w -X main.version=$VERSION -X main.commit=$COMMIT" \
|
||||
-o "$out" ./cmd/talk
|
||||
done
|
||||
(cd "$DIST" && sha256sum talk_* > checksums.txt)
|
||||
echo
|
||||
echo "Version $VERSION ($COMMIT):"
|
||||
cat "$DIST/checksums.txt"
|
||||
Reference in new issue
Block a user