Vendor Tailwind and daisyUI in the repo; never reach github.com

Builds used to download the Tailwind binary and the daisyUI plugins from GitHub
releases. They are now committed in tools/tailwind/:
- the Tailwind 4.3.3 standalone binary for linux-x64, xz -9e compressed (28 MB);
- daisyui.mjs and daisyui-theme.mjs 5.7.47;
- daisyUI's llms.txt component reference;
- Tailwind's MIT license.

tools/tailwind.sh no longer touches the network. "prepare" checks every file
against its pinned sha256 and unpacks the binary into .tools/. MSBuild reruns it
only when the archive or the script changes. A build from scratch was checked
inside a network namespace with no network at all.

.gitattributes keeps the vendored files byte-exact, and Tailwind no longer scans
tools/, whose llms.txt names every daisyUI class.

Both workflows used actions/checkout, which a Gitea runner downloads from
github.com. They now git fetch the commit from this Gitea, as they already did
for SocialPub.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LsXgEaXee4GCU1hwYgPJXw
This commit is contained in:
thepraandClaude Opus 5.5 committed 2026-10-03 12:43:07 +02:00
1 parent e075c4040b
commit a097338121
12 files changed
+3667 -72

No files matched your search

+44 -52
View File
@@ -1,25 +1,27 @@
#!/usr/bin/env bash
# Tailwind CSS standalone + daisyUI, with no Node. MSBuild runs `fetch` (decePubClient.csproj, EnsureTailwindTools)
# and then compiles Styles/app.css itself; run `watch` beside `dotnet watch` for live CSS work.
# bash tools/tailwind.sh fetch download and verify the pinned binaries into .tools/tailwind/
# Tailwind CSS standalone + daisyUI, vendored in tools/tailwind/ so building never touches the network.
# MSBuild runs `prepare` (EnsureTailwindTools in decePubClient.csproj) and then compiles Styles/app.css itself.
# bash tools/tailwind.sh prepare verify the vendored files and unpack the binary into .tools/tailwind/
# bash tools/tailwind.sh build one-off build of wwwroot/css/app.css (what MSBuild does in Debug)
# bash tools/tailwind.sh watch rebuild wwwroot/css/app.css on every change
# bash tools/tailwind.sh docs fetch daisyUI's llms.txt (component reference, unpinned) into .tools/tailwind/
# bash tools/tailwind.sh watch rebuild wwwroot/css/app.css on every change, beside `dotnet watch`
#
# tools/tailwind/ holds:
# tailwindcss-linux-x64.xz the Tailwind CSS v4.3.3 standalone binary, xz -9e compressed
# daisyui.mjs, daisyui-theme.mjs the daisyUI v5.7.47 plugins (Styles/app.css and Styles/theme.css load them)
# daisyui-llms.txt daisyUI's component reference for v5.7.x, read when writing Components/Daisy
#
# To upgrade, take the new release assets (tailwindcss-linux-x64 from Tailwind's release, daisyui.mjs and
# daisyui-theme.mjs from daisyUI's), check them against the checksums the projects publish, replace the files here
# (`xz -9e -c tailwindcss-linux-x64 > tools/tailwind/tailwindcss-linux-x64.xz`), and update the versions and every
# sha256 below. Only linux-x64 is vendored; another platform needs its binary added the same way.
set -euo pipefail
TAILWIND_VERSION=4.3.3
DAISYUI_VERSION=5.7.47
# sha256 of each release asset. Tailwind's are from its release sha256sums.txt; daisyUI publishes none, so these were
# computed from the v5.7.47 release assets.
pinned_sha256() {
case "$1" in
tailwindcss-linux-x64) echo dc61b3ac6b8c9ca874c0cc4c57b2409791a64c5540404ca5f5367360babc313a ;;
tailwindcss-linux-x64-musl) echo a04d34ceacc8f52cbe8920ad846cdeb61d3d0021dba32db0d1f77c9d9fad7a6c ;;
tailwindcss-linux-arm64) echo 55fd0b241214eff3de1e8ee4f22796662f2d2e7a49bcfca7477cfd0bac398195 ;;
tailwindcss-linux-arm64-musl) echo 71ea4be79c9de9827545682df3e040053fb535d37c71ed2cfdedf9385a0868e0 ;;
tailwindcss-macos-x64) echo 7922e0953f2110c05976e3bf58f14e643d90427575e766b7d433f5f80cbee7e1 ;;
tailwindcss-macos-arm64) echo cdf646702987a743464dff4d9c60fd4480d1c1e73dd819a9a67f1078815dce9d ;;
tailwindcss-linux-x64.xz) echo 8ad24bb6ac4f615fa9a1abdf4b49143690eaa5531a62a49e89f4eab0c91ad02b ;;
daisyui.mjs) echo 85819d3fe86a852237b439b13f481481aac58e562ac47694cd11c3038e994f2a ;;
daisyui-theme.mjs) echo d92d2f488933dab757f046e81ebd4986e51e9423307798dc3545d09a15542c89 ;;
*) echo "tailwind.sh: no pinned checksum for $1" >&2; exit 1 ;;
@@ -27,62 +29,52 @@ pinned_sha256() {
}
ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
VENDOR="$ROOT/tools/tailwind"
TOOLS="$ROOT/.tools/tailwind"
TAILWIND="$TOOLS/tailwindcss"
tailwind_asset() {
local os arch libc=""
case "$(uname -s)" in
Linux) os=linux ;;
Darwin) os=macos ;;
*) echo "tailwind.sh: unsupported OS $(uname -s)" >&2; exit 1 ;;
platform() {
case "$(uname -s)-$(uname -m)" in
Linux-x86_64|Linux-amd64) echo linux-x64 ;;
*) echo "tailwind.sh: only the linux-x64 Tailwind binary is vendored (this is $(uname -s)-$(uname -m))" >&2; exit 1 ;;
esac
case "$(uname -m)" in
x86_64|amd64) arch=x64 ;;
aarch64|arm64) arch=arm64 ;;
*) echo "tailwind.sh: unsupported architecture $(uname -m)" >&2; exit 1 ;;
esac
if [ "$os" = linux ] && ldd --version 2>&1 | grep -qi musl; then libc=-musl; fi
echo "tailwindcss-$os-$arch$libc"
}
sha256_of() {
if command -v sha256sum >/dev/null; then sha256sum "$1" | cut -d' ' -f1; else shasum -a 256 "$1" | cut -d' ' -f1; fi
}
# fetch_one <url> <destination> <expected sha256>
fetch_one() {
local url="$1" dest="$2" expected="$3"
if [ -f "$dest" ] && [ "$(sha256_of "$dest")" = "$expected" ]; then return; fi
echo "tailwind.sh: downloading $url"
curl -fsSL --retry 3 -o "$dest.part" "$url"
local actual
actual="$(sha256_of "$dest.part")"
# verify <file> <pinned name>
verify() {
local actual expected
actual="$(sha256_of "$1")"
expected="$(pinned_sha256 "$2")"
if [ "$actual" != "$expected" ]; then
rm -f "$dest.part"
echo "tailwind.sh: checksum mismatch for $url (expected $expected, got $actual)" >&2
exit 1
echo "tailwind.sh: checksum mismatch for $1 (expected $expected, got $actual)" >&2
return 1
fi
mv "$dest.part" "$dest"
}
fetch() {
mkdir -p "$TOOLS"
prepare() {
local asset
asset="$(tailwind_asset)"
fetch_one "https://github.com/tailwindlabs/tailwindcss/releases/download/v$TAILWIND_VERSION/$asset" \
"$TAILWIND" "$(pinned_sha256 "$asset")"
chmod +x "$TAILWIND"
for f in daisyui.mjs daisyui-theme.mjs; do
fetch_one "https://github.com/saadeghi/daisyui/releases/download/v$DAISYUI_VERSION/$f" "$TOOLS/$f" "$(pinned_sha256 "$f")"
done
asset="tailwindcss-$(platform)"
verify "$VENDOR/daisyui.mjs" daisyui.mjs
verify "$VENDOR/daisyui-theme.mjs" daisyui-theme.mjs
if [ -f "$TAILWIND" ] && verify "$TAILWIND" "$asset" 2>/dev/null; then return; fi
command -v xz >/dev/null || { echo "tailwind.sh: xz is needed to unpack $asset.xz" >&2; exit 1; }
verify "$VENDOR/$asset.xz" "$asset.xz"
echo "tailwind.sh: unpacking Tailwind CSS v$TAILWIND_VERSION ($asset) into .tools/tailwind/"
mkdir -p "$TOOLS"
xz -dc "$VENDOR/$asset.xz" > "$TAILWIND.part"
verify "$TAILWIND.part" "$asset" || { rm -f "$TAILWIND.part"; exit 1; }
chmod +x "$TAILWIND.part"
mv "$TAILWIND.part" "$TAILWIND"
}
cd "$ROOT"
case "${1:-build}" in
fetch) fetch ;;
build) fetch; "$TAILWIND" -i Styles/app.css -o wwwroot/css/app.css --optimize ;;
watch) fetch; exec "$TAILWIND" -i Styles/app.css -o wwwroot/css/app.css --watch ;;
docs) mkdir -p "$TOOLS"; curl -fsSL -o "$TOOLS/llms.txt" https://daisyui.com/llms.txt; echo "$TOOLS/llms.txt" ;;
*) echo "usage: tailwind.sh [fetch|build|watch|docs]" >&2; exit 2 ;;
prepare) prepare ;;
build) prepare; "$TAILWIND" -i Styles/app.css -o wwwroot/css/app.css --optimize ;;
watch) prepare; exec "$TAILWIND" -i Styles/app.css -o wwwroot/css/app.css --watch ;;
*) echo "usage: tailwind.sh [prepare|build|watch]" >&2; exit 2 ;;
esac
+24
View File
@@ -0,0 +1,24 @@
Applies to tailwindcss-linux-x64.xz, the Tailwind CSS standalone executable (https://tailwindcss.com).
daisyui.mjs and daisyui-theme.mjs carry their own MIT license at the end of each file.
MIT License
Copyright (c) Tailwind Labs, Inc.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
File diff suppressed because it is too large. Load diff
+95
View File
@@ -0,0 +1,95 @@
/** 🌼
* @license MIT
* daisyUI bundle
* https://daisyui.com/
*/
// packages/daisyui/functions/plugin.js
var plugin = {
withOptions: (pluginFunction, configFunction = () => ({})) => {
const optionsFunction = (options) => {
const handler = pluginFunction(options);
const config = configFunction(options);
return { handler, config };
};
optionsFunction.__isOptionsFunction = true;
return optionsFunction;
}
};
// packages/daisyui/theme/object.js
var object_default = { synthwave: { "color-scheme": "dark", "--color-base-100": "oklch(15% 0.09 281.288)", "--color-base-200": "oklch(20% 0.09 281.288)", "--color-base-300": "oklch(25% 0.09 281.288)", "--color-base-content": "oklch(78% 0.115 274.713)", "--color-primary": "oklch(71% 0.202 349.761)", "--color-primary-content": "oklch(28% 0.109 3.907)", "--color-secondary": "oklch(82% 0.111 230.318)", "--color-secondary-content": "oklch(29% 0.066 243.157)", "--color-accent": "oklch(75% 0.183 55.934)", "--color-accent-content": "oklch(26% 0.079 36.259)", "--color-neutral": "oklch(45% 0.24 277.023)", "--color-neutral-content": "oklch(87% 0.065 274.039)", "--color-info": "oklch(74% 0.16 232.661)", "--color-info-content": "oklch(29% 0.066 243.157)", "--color-success": "oklch(77% 0.152 181.912)", "--color-success-content": "oklch(27% 0.046 192.524)", "--color-warning": "oklch(90% 0.182 98.111)", "--color-warning-content": "oklch(42% 0.095 57.708)", "--color-error": "oklch(73.7% 0.121 32.639)", "--color-error-content": "oklch(23.501% 0.096 290.329)", "--radius-selector": "1rem", "--radius-field": "0.5rem", "--radius-box": "1rem", "--size-selector": "0.25rem", "--size-field": "0.25rem", "--border": "1px", "--depth": "0", "--noise": "0" }, sunset: { "color-scheme": "dark", "--color-base-100": "oklch(22% 0.019 237.69)", "--color-base-200": "oklch(20% 0.019 237.69)", "--color-base-300": "oklch(18% 0.019 237.69)", "--color-base-content": "oklch(77.383% 0.043 245.096)", "--color-primary": "oklch(74.703% 0.158 39.947)", "--color-primary-content": "oklch(14.94% 0.031 39.947)", "--color-secondary": "oklch(72.537% 0.177 2.72)", "--color-secondary-content": "oklch(14.507% 0.035 2.72)", "--color-accent": "oklch(71.294% 0.166 299.844)", "--color-accent-content": "oklch(14.258% 0.033 299.844)", "--color-neutral": "oklch(26% 0.019 237.69)", "--color-neutral-content": "oklch(70% 0.019 237.69)", "--color-info": "oklch(85.559% 0.085 206.015)", "--color-info-content": "oklch(17.111% 0.017 206.015)", "--color-success": "oklch(85.56% 0.085 144.778)", "--color-success-content": "oklch(17.112% 0.017 144.778)", "--color-warning": "oklch(85.569% 0.084 74.427)", "--color-warning-content": "oklch(17.113% 0.016 74.427)", "--color-error": "oklch(85.511% 0.078 16.886)", "--color-error-content": "oklch(17.102% 0.015 16.886)", "--radius-selector": "1rem", "--radius-field": "0.5rem", "--radius-box": "1rem", "--size-selector": "0.25rem", "--size-field": "0.25rem", "--border": "1px", "--depth": "0", "--noise": "0" }, dracula: { "color-scheme": "dark", "--color-base-100": "oklch(28.822% 0.022 277.508)", "--color-base-200": "oklch(26.805% 0.02 277.508)", "--color-base-300": "oklch(24.787% 0.019 277.508)", "--color-base-content": "oklch(97.747% 0.007 106.545)", "--color-primary": "oklch(75.461% 0.183 346.812)", "--color-primary-content": "oklch(15.092% 0.036 346.812)", "--color-secondary": "oklch(74.202% 0.148 301.883)", "--color-secondary-content": "oklch(14.84% 0.029 301.883)", "--color-accent": "oklch(83.392% 0.124 66.558)", "--color-accent-content": "oklch(16.678% 0.024 66.558)", "--color-neutral": "oklch(39.445% 0.032 275.524)", "--color-neutral-content": "oklch(87.889% 0.006 275.524)", "--color-info": "oklch(88.263% 0.093 212.846)", "--color-info-content": "oklch(17.652% 0.018 212.846)", "--color-success": "oklch(87.099% 0.219 148.024)", "--color-success-content": "oklch(17.419% 0.043 148.024)", "--color-warning": "oklch(95.533% 0.134 112.757)", "--color-warning-content": "oklch(19.106% 0.026 112.757)", "--color-error": "oklch(68.22% 0.206 24.43)", "--color-error-content": "oklch(13.644% 0.041 24.43)", "--radius-selector": "1rem", "--radius-field": "0.5rem", "--radius-box": "1rem", "--size-selector": "0.25rem", "--size-field": "0.25rem", "--border": "1px", "--depth": "0", "--noise": "0" }, caramellatte: { "color-scheme": "light", "--color-base-100": "oklch(98% 0.016 73.684)", "--color-base-200": "oklch(95% 0.038 75.164)", "--color-base-300": "oklch(90% 0.076 70.697)", "--color-base-content": "oklch(40% 0.123 38.172)", "--color-primary": "oklch(0% 0 0)", "--color-primary-content": "oklch(100% 0 0)", "--color-secondary": "oklch(22.45% 0.075 37.85)", "--color-secondary-content": "oklch(90% 0.076 70.697)", "--color-accent": "oklch(46.44% 0.111 37.85)", "--color-accent-content": "oklch(90% 0.076 70.697)", "--color-neutral": "oklch(55% 0.195 38.402)", "--color-neutral-content": "oklch(98% 0.016 73.684)", "--color-info": "oklch(42% 0.199 265.638)", "--color-info-content": "oklch(90% 0.076 70.697)", "--color-success": "oklch(43% 0.095 166.913)", "--color-success-content": "oklch(90% 0.076 70.697)", "--color-warning": "oklch(82% 0.189 84.429)", "--color-warning-content": "oklch(41% 0.112 45.904)", "--color-error": "oklch(70% 0.191 22.216)", "--color-error-content": "oklch(39% 0.141 25.723)", "--radius-selector": "2rem", "--radius-field": "0.5rem", "--radius-box": "1rem", "--size-selector": "0.25rem", "--size-field": "0.25rem", "--border": "2px", "--depth"Line truncated
// packages/daisyui/theme/index.js
var escapeCssString = (value) => String(value).replace(/[^a-zA-Z0-9_-]/gu, (character) => `\\${character.codePointAt(0).toString(16)} `);
var theme_default = plugin.withOptions((options = {}) => {
return ({ addBase }) => {
const {
name = "custom-theme",
default: isDefault = false,
prefersdark = false,
"color-scheme": colorScheme,
root = ":root",
...customThemeTokens
} = options;
const escapedName = escapeCssString(name);
let selector = `${root}:has(input.theme-controller[value="${escapedName}"]:checked),[data-theme="${escapedName}"]`;
if (isDefault) {
selector = `:where(${root}),${selector}`;
}
let themeTokens = { ...customThemeTokens };
if (object_default[name]) {
const builtinTheme = object_default[name];
themeTokens = {
...builtinTheme,
...customThemeTokens,
"color-scheme": colorScheme ?? builtinTheme["color-scheme"]
};
}
const baseStyles = {
[selector]: {
"color-scheme": themeTokens["color-scheme"] ?? colorScheme ?? "normal",
...themeTokens
}
};
if (prefersdark) {
const darkSelector = root === ":root" ? ":root:not([data-theme])" : `${root}:not([data-theme])`;
addBase({
"@media (prefers-color-scheme: dark)": {
[darkSelector]: baseStyles[selector]
}
});
}
addBase(baseStyles);
};
});
export {
theme_default as default
};
/*
MIT License
Copyright (c) 2020 Pouya Saadeghi – https://daisyui.com
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
File diff suppressed because it is too large. Load diff
Binary file not shown.