tribes: build assets in source package release flow

This commit is contained in:
2026-04-04 15:39:47 +02:00
parent 7ffffb255b
commit 9ae6d1e600
4 changed files with 177 additions and 15 deletions

View File

@@ -20,8 +20,10 @@ It now also carries the first Tribes deployment substrate:
- `tribes/packages/release.scm` - `tribes/packages/release.scm`
A deployment-bridge package wrapper for a prebuilt Tribes release tree. A deployment-bridge package wrapper for a prebuilt Tribes release tree.
- `tribes/packages/source.scm` - `tribes/packages/source.scm`
A real source-built Tribes package that produces a production release from a A real source-built Tribes package that produces a production release from
vendored Mix dependency tree plus local Parrhesia source. vendored Mix and npm dependency trees plus local Parrhesia source.
Local-source builds accept hash overrides via `TRIBES_MIX_DEPS_SHA256`,
`TRIBES_RAW_MIX_DEPS_SHA256`, and `TRIBES_NPM_DEPS_SHA256`.
- `tribes/services/tribes.scm` - `tribes/services/tribes.scm`
Shepherd service, runtime environment wiring, and account/activation setup Shepherd service, runtime environment wiring, and account/activation setup
for a Tribes node. for a Tribes node.

View File

@@ -27,7 +27,8 @@
source-directory source-directory
#:version (getenv/default "TRIBES_RELEASE_VERSION" "dev") #:version (getenv/default "TRIBES_RELEASE_VERSION" "dev")
#:mix-deps-sha256 (getenv "TRIBES_MIX_DEPS_SHA256") #:mix-deps-sha256 (getenv "TRIBES_MIX_DEPS_SHA256")
#:raw-mix-deps-sha256 (getenv "TRIBES_RAW_MIX_DEPS_SHA256")) #:raw-mix-deps-sha256 (getenv "TRIBES_RAW_MIX_DEPS_SHA256")
#:npm-deps-sha256 (getenv "TRIBES_NPM_DEPS_SHA256"))
tribes-package))) tribes-package)))
(define (make-tribes-node-manifest) (define (make-tribes-node-manifest)

View File

@@ -11,12 +11,14 @@
#:use-module (gnu packages gawk) #:use-module (gnu packages gawk)
#:use-module (gnu packages linux) #:use-module (gnu packages linux)
#:use-module (gnu packages m4) #:use-module (gnu packages m4)
#:use-module (gnu packages node)
#:use-module (gnu packages perl) #:use-module (gnu packages perl)
#:use-module (gnu packages pkg-config) #:use-module (gnu packages pkg-config)
#:use-module ((tribes packages mix) #:prefix mix:) #:use-module ((tribes packages mix) #:prefix mix:)
#:use-module (srfi srfi-1) #:use-module (srfi srfi-1)
#:use-module (srfi srfi-13) #:use-module (srfi srfi-13)
#:export (fetch-mix-deps #:export (fetch-mix-deps
fetch-npm-deps
local-tribes-package local-tribes-package
tribes-package tribes-package
tribes-source-package tribes-source-package
@@ -34,6 +36,12 @@
(define %tribes-mix-deps-sha256 (define %tribes-mix-deps-sha256
"0ksjnc9gnjijp1nbz3jlvl9kz8w7hx1a0ssms1dvd15rr25gn0d4") "0ksjnc9gnjijp1nbz3jlvl9kz8w7hx1a0ssms1dvd15rr25gn0d4")
;; Recursive sha256 of assets/node_modules generated from assets/package-lock.json
;; in an isolated build environment, with local file dependencies resolved from
;; the vendored Mix dependency tree.
(define %tribes-npm-deps-sha256
"1bfzs67ffhwcm0dwdkb1jqnbn3fpgj22zfhd2y907w8daj62gahv")
(define %tribes-home-page (define %tribes-home-page
"https://git.teralink.net/tribes/tribes.git") "https://git.teralink.net/tribes/tribes.git")
@@ -68,6 +76,16 @@
(sha256 (sha256
(base32 "10cvh8jks3rjg6p7y0vm1v4kw9y7vljbfijj0zxwkxzysxx60w0f")))) (base32 "10cvh8jks3rjg6p7y0vm1v4kw9y7vljbfijj0zxwkxzysxx60w0f"))))
(define %heroicons-upstream-source
(origin
(method git-fetch)
(uri (git-reference
(url "https://github.com/tailwindlabs/heroicons")
(commit "0435d4ca364a608cc75e2f8683d374e55abbae26")))
(file-name (git-file-name "heroicons" "2.2.0"))
(sha256
(base32 "15di4p755ydivkbv9mv9hb8lsdgzb5zq77ljdnyp76cvykanpk15"))))
(define %excluded-root-basenames (define %excluded-root-basenames
'(".cache" '(".cache"
".claude" ".claude"
@@ -125,6 +143,86 @@ checkout."
(define fetch-mix-deps mix:fetch-mix-deps) (define fetch-mix-deps mix:fetch-mix-deps)
(define* (fetch-npm-deps source
#:key
mix-fod-deps
(name "tribes-npm-deps")
(version "0.2.0")
(sha256 %tribes-npm-deps-sha256))
"Return a fixed-output node_modules tree for SOURCE/assets/package-lock.json,
with local file dependencies resolved from MIX-FOD-DEPS."
(computed-file
(string-append name "-" version)
(with-imported-modules '((guix build utils))
#~(begin
(use-modules (guix build utils))
(define out #$output)
(define work (string-append (getcwd) "/build"))
(define app-dir (string-append work "/app"))
(define deps-dir (string-append app-dir "/deps"))
(define assets-dir (string-append app-dir "/assets"))
(define certs-dir
#$(file-append nss-certs "/etc/ssl/certs"))
(define cert-file
(string-append work "/ca-certificates.crt"))
(define path
(string-join
(list #$(file-append node "/bin")
#$(file-append bash-minimal "/bin")
#$(file-append coreutils "/bin")
#$(file-append findutils "/bin")
#$(file-append git-minimal "/bin")
#$(file-append gzip "/bin")
#$(file-append tar "/bin")
(or (getenv "PATH") ""))
":"))
(mkdir-p work)
(copy-recursively #+source app-dir #:follow-symlinks? #t)
(invoke #$(file-append coreutils "/bin/chmod") "-R" "u+w" app-dir)
(when (file-exists? deps-dir)
(delete-file-recursively deps-dir))
(copy-recursively #+mix-fod-deps deps-dir #:follow-symlinks? #t)
(invoke #$(file-append coreutils "/bin/chmod") "-R" "u+w" deps-dir)
(invoke #$(file-append bash-minimal "/bin/sh")
"-c"
(string-append
#$(file-append coreutils "/bin/cat")
" "
certs-dir
"/*.pem > "
cert-file))
(setenv "PATH" path)
(setenv "HOME" (string-append work "/home"))
(setenv "XDG_CACHE_HOME" (string-append work "/cache"))
(setenv "npm_config_cache" (string-append work "/npm-cache"))
(setenv "npm_config_userconfig" (string-append work "/npmrc"))
(setenv "SSL_CERT_DIR" certs-dir)
(setenv "SSL_CERT_FILE" cert-file)
(setenv "NODE_ENV" "production")
(mkdir-p (getenv "HOME"))
(mkdir-p (getenv "XDG_CACHE_HOME"))
(mkdir-p (getenv "npm_config_cache"))
(with-directory-excursion assets-dir
(invoke "npm" "ci" "--ignore-scripts" "--no-audit" "--no-fund"))
(mkdir-p out)
(copy-recursively (string-append assets-dir "/node_modules")
out
#:follow-symlinks? #t)))
#:options
`(#:hash ,(base32 sha256)
#:hash-algo sha256
#:recursive? #t
#:leaked-env-vars ("http_proxy" "https_proxy"
"LC_ALL" "LC_MESSAGES" "LANG" "COLUMNS"))))
(define* (tribes-mix-deps source (define* (tribes-mix-deps source
#:key #:key
(name "tribes-mix-deps") (name "tribes-mix-deps")
@@ -192,22 +290,32 @@ resolution by injecting extra pre-fetched sources needed for offline builds."
(mix-deps-sha256 %tribes-mix-deps-sha256) (mix-deps-sha256 %tribes-mix-deps-sha256)
(raw-mix-deps-sha256 (raw-mix-deps-sha256
%tribes-raw-mix-deps-sha256) %tribes-raw-mix-deps-sha256)
(npm-deps #f)
(npm-deps-sha256 %tribes-npm-deps-sha256)
(name "tribes") (name "tribes")
(version %tribes-version) (version %tribes-version)
(home-page %tribes-home-page) (home-page %tribes-home-page)
(synopsis "Tribes social app") (synopsis "Tribes social app")
(description (description
"Tribes social application built from source as a "Tribes social application built from source as a
production Elixir release using a vendored Mix dependency tree.")) production Elixir release using vendored Mix and npm dependency trees."))
"Return a Guix package that builds a production Tribes release from SOURCE, "Return a Guix package that builds a production Tribes release from SOURCE,
using MIX-DEPS as the pre-fetched Mix dependency tree resolved from mix.lock." using MIX-DEPS and NPM-DEPS as pre-fetched dependency trees resolved from
(let ((mix-deps-source mix.lock and assets/package-lock.json."
(let* ((mix-deps-source
(or mix-deps (or mix-deps
(tribes-mix-deps source (tribes-mix-deps source
#:name (string-append name "-mix-deps") #:name (string-append name "-mix-deps")
#:version version #:version version
#:sha256 mix-deps-sha256 #:sha256 mix-deps-sha256
#:raw-sha256 raw-mix-deps-sha256)))) #:raw-sha256 raw-mix-deps-sha256)))
(npm-deps-source
(or npm-deps
(fetch-npm-deps source
#:mix-fod-deps mix-deps-source
#:name (string-append name "-npm-deps")
#:version version
#:sha256 npm-deps-sha256))))
(mix:mix-release-package (mix:mix-release-package
source source
#:mix-fod-deps mix-deps-source #:mix-fod-deps mix-deps-source
@@ -228,6 +336,7 @@ using MIX-DEPS as the pre-fetched Mix dependency tree resolved from mix.lock."
libtool libtool
linux-libre-headers linux-libre-headers
m4 m4
node
perl perl
pkg-config pkg-config
sed) sed)
@@ -241,6 +350,7 @@ using MIX-DEPS as the pre-fetched Mix dependency tree resolved from mix.lock."
gnu-make gnu-make
libtool libtool
m4 m4
node
perl perl
pkg-config pkg-config
sed) sed)
@@ -284,6 +394,51 @@ using MIX-DEPS as the pre-fetched Mix dependency tree resolved from mix.lock."
(setenv "ERL_FLAGS" existing-erl-flags) (setenv "ERL_FLAGS" existing-erl-flags)
(unsetenv "ERL_FLAGS"))) (unsetenv "ERL_FLAGS")))
(invoke "mix" "deps.compile")) (invoke "mix" "deps.compile"))
#:build-gexp
#~(begin
(invoke "mix" "compile" "--no-deps-check")
(let ((assets-node-modules "assets/node_modules"))
(when (file-exists? assets-node-modules)
(delete-file-recursively assets-node-modules))
(copy-recursively #+npm-deps-source
assets-node-modules
#:follow-symlinks? #t)
(invoke #$(file-append coreutils "/bin/chmod")
"-R"
"u+w"
assets-node-modules)
(invoke "find"
assets-node-modules
"-type" "f"
"-path" "*/@esbuild/*/bin/esbuild"
"-exec" "chmod" "+x" "{}" "+")
(invoke "find"
assets-node-modules
"-type" "f"
"-path" "*/.bin/*"
"-exec" "chmod" "+x" "{}" "+"))
(let ((heroicons-dir "deps/heroicons"))
(when (file-exists? heroicons-dir)
(delete-file-recursively heroicons-dir))
(copy-recursively #+%heroicons-upstream-source
heroicons-dir
#:follow-symlinks? #t)
(invoke #$(file-append coreutils "/bin/chmod")
"-R"
"u+w"
heroicons-dir))
(setenv "NODE_PATH"
(string-append (getcwd) "/deps:"
(getcwd) "/_build/prod"))
(with-directory-excursion "assets"
(invoke "npm" "run" "build.css" "--" "--minify")
(invoke "npm" "run" "build.js" "--" "--minify"))
(invoke "mix" "phx.digest"))
#:install-gexp #:install-gexp
#~(begin #~(begin
(invoke "mix" "release" "--no-deps-check" "--path" out) (invoke "mix" "release" "--no-deps-check" "--path" out)
@@ -296,16 +451,19 @@ using MIX-DEPS as the pre-fetched Mix dependency tree resolved from mix.lock."
#:key #:key
(version "dev") (version "dev")
(mix-deps-sha256 #f) (mix-deps-sha256 #f)
(raw-mix-deps-sha256 #f)) (raw-mix-deps-sha256 #f)
(npm-deps-sha256 #f))
"Return a Tribes package built from a local source checkout. Hash overrides "Return a Tribes package built from a local source checkout. Hash overrides
allow development against a changed mix.lock without changing the canonical allow development against changed lockfiles without changing the canonical
package pin." package pin."
(tribes-source-package (tribes-source-package
(tribes-source-directory->local-file directory) (tribes-source-directory->local-file directory)
#:version version #:version version
#:mix-deps-sha256 (or mix-deps-sha256 %tribes-mix-deps-sha256) #:mix-deps-sha256 (or mix-deps-sha256 %tribes-mix-deps-sha256)
#:raw-mix-deps-sha256 #:raw-mix-deps-sha256
(or raw-mix-deps-sha256 %tribes-raw-mix-deps-sha256))) (or raw-mix-deps-sha256 %tribes-raw-mix-deps-sha256)
#:npm-deps-sha256
(or npm-deps-sha256 %tribes-npm-deps-sha256)))
(define tribes-package (define tribes-package
(tribes-source-package %tribes-upstream-source (tribes-source-package %tribes-upstream-source

View File

@@ -51,7 +51,8 @@
source-directory source-directory
#:version (getenv/default "TRIBES_RELEASE_VERSION" "dev") #:version (getenv/default "TRIBES_RELEASE_VERSION" "dev")
#:mix-deps-sha256 (getenv "TRIBES_MIX_DEPS_SHA256") #:mix-deps-sha256 (getenv "TRIBES_MIX_DEPS_SHA256")
#:raw-mix-deps-sha256 (getenv "TRIBES_RAW_MIX_DEPS_SHA256")) #:raw-mix-deps-sha256 (getenv "TRIBES_RAW_MIX_DEPS_SHA256")
#:npm-deps-sha256 (getenv "TRIBES_NPM_DEPS_SHA256"))
tribes-package))) tribes-package)))
(define* (tribes-installer-operating-system #:key (define* (tribes-installer-operating-system #:key