phase 1: copy Kindred-only files onto upstream/main (FreeCAD 1.2.0-dev)

Wholesale copy of all Kindred Create additions that don't conflict with
upstream FreeCAD code:

- kindred-icons/ (1444 Catppuccin Mocha SVG icon overrides)
- src/Mod/Create/ (Kindred Create workbench)
- src/Gui/ Kindred source files (FileOrigin, OriginManager,
  OriginSelectorWidget, CommandOrigin, BreadcrumbToolBar, EditingContext)
- src/Gui/Icons/ (Kindred branding and silo icons)
- src/Gui/PreferencePacks/KindredCreate/
- src/Gui/Stylesheets/ (KindredCreate.qss, images_dark-light/)
- package/ (rattler-build recipe)
- docs/ (architecture, guides, specifications)
- .gitea/ (CI workflows, issue templates)
- mods/silo, mods/ztools submodules
- .gitmodules (Kindred submodule URLs)
- resources/ (kindred-create.desktop, kindred-create.xml)
- banner-logo-light.png, CONTRIBUTING.md
This commit is contained in:
forbes
2026-02-13 14:03:58 -06:00
parent 5d81f8ac16
commit 87a0af0b0f
1566 changed files with 32071 additions and 6155 deletions

146
.gitea/workflows/build.yml Normal file
View File

@@ -0,0 +1,146 @@
# SPDX-License-Identifier: LGPL-2.1-or-later
name: Build and Test
on:
push:
branches: [main]
pull_request:
branches: [main]
workflow_dispatch:
jobs:
build:
runs-on: ubuntu-latest
env:
CCACHE_DIR: /tmp/ccache-kindred-create
CCACHE_COMPRESS: "true"
CCACHE_COMPRESSLEVEL: "6"
CCACHE_MAXSIZE: "4G"
CCACHE_SLOPPINESS: "include_file_ctime,include_file_mtime,pch_defines,time_macros"
CCACHE_COMPILERCHECK: "content"
CCACHE_BASEDIR: ${{ github.workspace }}
DEBIAN_FRONTEND: noninteractive
NODE_EXTRA_CA_CERTS: /etc/ssl/certs/ca-certificates.crt
steps:
- name: Trust Cloudflare origin CA
run: |
apt-get update -qq
apt-get install -y --no-install-recommends ca-certificates
update-ca-certificates
- name: Free disk space
run: |
echo "=== Disk usage before cleanup ==="
df -h /
rm -rf /usr/share/dotnet /usr/local/lib/android /opt/ghc /opt/hostedtoolcache 2>/dev/null || true
rm -rf /usr/local/share/boost /usr/share/swift 2>/dev/null || true
apt-get autoremove -y 2>/dev/null || true
apt-get clean 2>/dev/null || true
echo "=== Disk usage after cleanup ==="
df -h /
- name: Install system prerequisites
run: |
apt-get update -qq
apt-get install -y --no-install-recommends \
ca-certificates curl git xvfb xauth openssl sudo \
libgl1-mesa-dev libglu1-mesa-dev libx11-dev libxkbcommon-dev \
libxcb-xkb-dev libfontconfig1-dev
- name: Checkout repository
uses: https://git.kindred-systems.com/actions/checkout.git@v4
with:
submodules: recursive
fetch-depth: 1
- name: Fetch latest tag (for git describe)
run: |
latest_tag=$(git ls-remote --tags --sort=-v:refname origin 'refs/tags/v*' | grep -v '\^{}' | head -n1 | awk '{print $2}')
if [ -n "$latest_tag" ]; then
git fetch --no-recurse-submodules --force --depth=1 origin "+${latest_tag}:${latest_tag}"
fi
- name: Install pixi
run: |
curl -fsSL https://pixi.sh/install.sh | bash
echo "$HOME/.pixi/bin" >> $GITHUB_PATH
export PATH="$HOME/.pixi/bin:$PATH"
pixi --version
- name: Run Kindred addon tests (pure logic, no build needed)
timeout-minutes: 2
run: python3 tests/run_kindred_tests.py
- name: Restore ccache
id: ccache-restore
uses: https://git.kindred-systems.com/actions/cache.git/restore@v4
with:
path: /tmp/ccache-kindred-create
key: ccache-build-${{ github.ref_name }}-${{ github.run_id }}
restore-keys: |
ccache-build-${{ github.ref_name }}-
ccache-build-main-
- name: Prepare ccache
run: |
mkdir -p $CCACHE_DIR
pixi run ccache -z
pixi run ccache -p
- name: Configure (CMake)
run: pixi run cmake --preset conda-linux-release
- name: Build
run: pixi run cmake --build build/release -j$(nproc)
- name: Show ccache statistics
run: pixi run ccache -s
- name: Save ccache
if: always()
uses: https://git.kindred-systems.com/actions/cache.git/save@v4
with:
path: /tmp/ccache-kindred-create
key: ccache-build-${{ github.ref_name }}-${{ github.run_id }}
- name: Run C++ unit tests
continue-on-error: true
timeout-minutes: 15
run: |
export CTEST_DISCOVERY_TIMEOUT=60
pixi run xvfb-run -a ctest --test-dir build/release \
--output-on-failure \
--timeout 120 \
--exclude-regex "Assembly_tests" \
2>&1 || true
- name: Install
run: pixi run cmake --install build/release --prefix build/release/install
- name: Run Python CLI tests
timeout-minutes: 10
run: pixi run timeout 300 build/release/bin/FreeCADCmd -t 0 || true
- name: Run GUI tests (headless)
timeout-minutes: 10
run: pixi run timeout 300 xvfb-run -a build/release/bin/FreeCAD -t 0 || true
- name: Package build artifacts
run: |
ARTIFACT_NAME="kindred-create-$(git describe --tags --always)-linux-x86_64"
cd build/release
cp -a install "${ARTIFACT_NAME}"
tar -cJf "${ARTIFACT_NAME}.tar.xz" "${ARTIFACT_NAME}"
sha256sum "${ARTIFACT_NAME}.tar.xz" > "${ARTIFACT_NAME}.tar.xz.sha256"
echo "ARTIFACT_NAME=${ARTIFACT_NAME}" >> $GITHUB_ENV
- name: Upload build artifact
uses: https://git.kindred-systems.com/actions/upload-artifact.git@v3
with:
name: ${{ env.ARTIFACT_NAME }}
path: |
build/release/*.tar.xz
build/release/*.sha256
retention-days: 14

51
.gitea/workflows/docs.yml Normal file
View File

@@ -0,0 +1,51 @@
name: Deploy Docs
on:
push:
branches: [main]
paths:
- "docs/**"
- ".gitea/workflows/docs.yml"
- ".gitea/workflows/sync-silo-docs.yml"
jobs:
build-and-deploy:
runs-on: docs
steps:
- name: Checkout
run: |
REPO_URL="http://gitea:3000/kindred/create.git"
if [ -d .git ]; then
git fetch "$REPO_URL" main
git checkout -f FETCH_HEAD
else
git clone --depth 1 --branch main "$REPO_URL" .
fi
- name: Install mdBook
run: |
if ! command -v mdbook &>/dev/null; then
MDBOOK_VERSION="v0.5.2"
wget -q -O mdbook.tar.gz "https://github.com/rust-lang/mdBook/releases/download/${MDBOOK_VERSION}/mdbook-${MDBOOK_VERSION}-x86_64-unknown-linux-musl.tar.gz"
tar -xzf mdbook.tar.gz -C /usr/local/bin
rm mdbook.tar.gz
fi
- name: Fetch Silo server docs
run: |
rm -rf /tmp/silo
git clone --depth 1 http://gitea:3000/kindred/silo.git /tmp/silo
mkdir -p docs/src/silo-server
cp /tmp/silo/docs/*.md docs/src/silo-server/
cp /tmp/silo/README.md docs/src/silo-server/overview.md
cp /tmp/silo/ROADMAP.md docs/src/silo-server/ROADMAP.md 2>/dev/null || true
cp /tmp/silo/frontend-spec.md docs/src/silo-server/frontend-spec.md 2>/dev/null || true
rm -rf /tmp/silo
- name: Build mdBook
run: mdbook build docs/
- name: Deploy
run: |
rm -rf /opt/git/docs/book/*
cp -r docs/book/* /opt/git/docs/book/

View File

@@ -0,0 +1,438 @@
# SPDX-License-Identifier: LGPL-2.1-or-later
name: Release Build
on:
push:
tags: ["v*", "latest"]
workflow_dispatch:
inputs:
tag:
description: "Release tag (e.g., v0.1.0)"
required: true
type: string
jobs:
# ---------------------------------------------------------------------------
# Linux: AppImage + .deb
# ---------------------------------------------------------------------------
build-linux:
runs-on: ubuntu-latest
env:
CCACHE_DIR: /tmp/ccache-kindred-create
CCACHE_COMPRESS: "true"
CCACHE_COMPRESSLEVEL: "6"
CCACHE_MAXSIZE: "4G"
CCACHE_SLOPPINESS: "include_file_ctime,include_file_mtime,pch_defines,time_macros"
CCACHE_COMPILERCHECK: "content"
CCACHE_BASEDIR: ${{ github.workspace }}
BUILD_TAG: ${{ github.ref_name || inputs.tag }}
CFLAGS: "-O3"
CXXFLAGS: "-O3"
DEBIAN_FRONTEND: noninteractive
NODE_EXTRA_CA_CERTS: /etc/ssl/certs/ca-certificates.crt
steps:
- name: Trust Cloudflare origin CA
run: |
apt-get update -qq
apt-get install -y --no-install-recommends ca-certificates
update-ca-certificates
- name: Free disk space
run: |
echo "=== Disk usage before cleanup ==="
df -h /
# Remove pre-installed bloat common in runner images
rm -rf /usr/share/dotnet /usr/local/lib/android /opt/ghc /opt/hostedtoolcache 2>/dev/null || true
rm -rf /usr/local/share/boost /usr/share/swift 2>/dev/null || true
apt-get autoremove -y 2>/dev/null || true
apt-get clean 2>/dev/null || true
echo "=== Disk usage after cleanup ==="
df -h /
- name: Install system prerequisites
run: |
apt-get update -qq
apt-get install -y --no-install-recommends \
ca-certificates curl git file fuse3 xvfb xauth openssl sudo dpkg-dev \
libgl1-mesa-dev libglu1-mesa-dev libx11-dev libxkbcommon-dev \
libxcb-xkb-dev libfontconfig1-dev
- name: Checkout repository
uses: https://git.kindred-systems.com/actions/checkout.git@v4
with:
submodules: recursive
fetch-depth: 1
- name: Fetch latest tag (for git describe)
run: |
latest_tag=$(git ls-remote --tags --sort=-v:refname origin 'refs/tags/v*' | grep -v '\^{}' | head -n1 | awk '{print $2}')
if [ -n "$latest_tag" ]; then
git fetch --no-recurse-submodules --force --depth=1 origin "+${latest_tag}:${latest_tag}"
fi
- name: Install pixi
run: |
curl -fsSL https://pixi.sh/install.sh | bash
echo "$HOME/.pixi/bin" >> $GITHUB_PATH
export PATH="$HOME/.pixi/bin:$PATH"
pixi --version
- name: Restore ccache
id: ccache-restore
uses: https://git.kindred-systems.com/actions/cache.git/restore@v4
with:
path: /tmp/ccache-kindred-create
key: ccache-release-linux-${{ github.run_id }}
restore-keys: |
ccache-release-linux-
ccache-build-main-
- name: Prepare ccache
run: |
mkdir -p $CCACHE_DIR
# Ensure ccache is accessible to rattler-build's subprocess
export PATH="$(pixi run bash -c 'echo $PATH')"
pixi run ccache -z
pixi run ccache -p
- name: Build release package (AppImage)
working-directory: package/rattler-build
run: |
pixi install
pixi run -e package create_bundle
- name: Show ccache statistics
run: pixi run ccache -s
- name: Save ccache
if: always()
uses: https://git.kindred-systems.com/actions/cache.git/save@v4
with:
path: /tmp/ccache-kindred-create
key: ccache-release-linux-${{ github.run_id }}
- name: Clean up intermediate build files
run: |
# Remove pixi package cache and build work dirs to free space for .deb
rm -rf package/rattler-build/.pixi/build 2>/dev/null || true
find /root/.cache/rattler -type f -delete 2>/dev/null || true
echo "=== Disk usage after cleanup ==="
df -h /
- name: Build .deb package
run: |
./package/debian/build-deb.sh \
package/rattler-build/linux/AppDir/usr \
package/rattler-build/linux \
"${BUILD_TAG}"
- name: List built artifacts
run: |
echo "=== Linux release artifacts ==="
ls -lah package/rattler-build/linux/*.AppImage* 2>/dev/null || true
ls -lah package/rattler-build/linux/*.deb* 2>/dev/null || true
ls -lah package/rattler-build/linux/*-SHA256.txt 2>/dev/null || true
- name: Upload Linux artifacts
uses: https://git.kindred-systems.com/actions/upload-artifact.git@v3
with:
name: release-linux
path: |
package/rattler-build/linux/FreeCAD_*.AppImage
package/rattler-build/linux/*.deb
package/rattler-build/linux/*-SHA256.txt
package/rattler-build/linux/*.sha256
if-no-files-found: error
# ---------------------------------------------------------------------------
# macOS: DMG (Intel + Apple Silicon)
# TODO: Re-enable when macOS runners are available or cross-compilation is set up
# ---------------------------------------------------------------------------
# build-macos:
# strategy:
# fail-fast: false
# matrix:
# include:
# - runner: macos-13
# arch: x86_64
# - runner: macos-14
# arch: arm64
#
# runs-on: ${{ matrix.runner }}
#
# env:
# CCACHE_DIR: /tmp/ccache-kindred-create
# CCACHE_COMPRESS: "true"
# CCACHE_COMPRESSLEVEL: "6"
# CCACHE_MAXSIZE: "4G"
# CCACHE_SLOPPINESS: "include_file_ctime,include_file_mtime,pch_defines,time_macros"
# CCACHE_BASEDIR: ${{ github.workspace }}
# BUILD_TAG: ${{ github.ref_name || inputs.tag }}
# CFLAGS: "-O3"
# CXXFLAGS: "-O3"
#
# steps:
# - name: Checkout repository
# uses: https://git.kindred-systems.com/actions/checkout.git@v4
# with:
# submodules: recursive
# fetch-depth: 1
#
# - name: Fetch tags
# run: git fetch --tags --force --no-recurse-submodules origin
#
# - name: Install pixi
# run: |
# curl -fsSL https://pixi.sh/install.sh | bash
# echo "$HOME/.pixi/bin" >> $GITHUB_PATH
# export PATH="$HOME/.pixi/bin:$PATH"
# pixi --version
#
# - name: Restore ccache
# id: ccache-restore
# uses: https://git.kindred-systems.com/actions/cache.git/restore@v4
# with:
# path: /tmp/ccache-kindred-create
# key: ccache-release-macos-${{ matrix.arch }}-${{ github.sha }}
# restore-keys: |
# ccache-release-macos-${{ matrix.arch }}-
#
# - name: Prepare ccache
# run: |
# mkdir -p $CCACHE_DIR
# pixi run ccache -z
#
# - name: Build release package (DMG)
# working-directory: package/rattler-build
# run: |
# pixi install
# pixi run -e package create_bundle
#
# - name: Show ccache statistics
# run: pixi run ccache -s
#
# - name: Save ccache
# if: always()
# uses: https://git.kindred-systems.com/actions/cache.git/save@v4
# with:
# path: /tmp/ccache-kindred-create
# key: ccache-release-macos-${{ matrix.arch }}-${{ github.sha }}
#
# - name: List built artifacts
# run: |
# echo "=== macOS ${{ matrix.arch }} release artifacts ==="
# ls -lah package/rattler-build/osx/*.dmg* 2>/dev/null || true
#
# - name: Upload macOS artifacts
# uses: https://git.kindred-systems.com/actions/upload-artifact.git@v3
# with:
# name: release-macos-${{ matrix.arch }}
# path: |
# package/rattler-build/osx/*.dmg
# package/rattler-build/osx/*-SHA256.txt
# if-no-files-found: error
# ---------------------------------------------------------------------------
# Windows: .exe installer + .7z archive
# TODO: Re-enable when Windows runners are available or cross-compilation is set up
# ---------------------------------------------------------------------------
# build-windows:
# runs-on: windows-latest
#
# env:
# CCACHE_DIR: C:\ccache-kindred-create
# CCACHE_COMPRESS: "true"
# CCACHE_COMPRESSLEVEL: "6"
# CCACHE_MAXSIZE: "4G"
# CCACHE_SLOPPINESS: "include_file_ctime,include_file_mtime,pch_defines,time_macros"
# CCACHE_BASEDIR: ${{ github.workspace }}
# BUILD_TAG: ${{ github.ref_name || inputs.tag }}
# CFLAGS: "/O2"
# CXXFLAGS: "/O2"
# MAKE_INSTALLER: "true"
#
# steps:
# - name: Checkout repository
# uses: https://git.kindred-systems.com/actions/checkout.git@v4
# with:
# submodules: recursive
# fetch-depth: 1
#
# - name: Fetch tags
# shell: bash
# run: git fetch --tags --force --no-recurse-submodules origin
#
# - name: Install pixi
# shell: bash
# run: |
# curl -fsSL https://pixi.sh/install.sh | bash
# echo "$HOME/.pixi/bin" >> $GITHUB_PATH
# export PATH="$HOME/.pixi/bin:$PATH"
# pixi --version
#
# - name: Restore ccache
# id: ccache-restore
# uses: https://git.kindred-systems.com/actions/cache.git/restore@v4
# with:
# path: C:\ccache-kindred-create
# key: ccache-release-windows-${{ github.sha }}
# restore-keys: |
# ccache-release-windows-
#
# - name: Build release package
# shell: bash
# working-directory: package/rattler-build
# run: |
# pixi install
# pixi run -e package create_bundle
#
# - name: Save ccache
# if: always()
# uses: https://git.kindred-systems.com/actions/cache.git/save@v4
# with:
# path: C:\ccache-kindred-create
# key: ccache-release-windows-${{ github.sha }}
#
# - name: List built artifacts
# shell: bash
# run: |
# echo "=== Windows release artifacts ==="
# ls -lah package/rattler-build/windows/*.7z* 2>/dev/null || true
# ls -lah package/rattler-build/windows/*.exe 2>/dev/null || true
# ls -lah package/rattler-build/windows/*-SHA256.txt 2>/dev/null || true
#
# - name: Upload Windows artifacts
# uses: https://git.kindred-systems.com/actions/upload-artifact.git@v3
# with:
# name: release-windows
# path: |
# package/rattler-build/windows/*.7z
# package/rattler-build/windows/*.exe
# package/rattler-build/windows/*-SHA256.txt
# if-no-files-found: error
# ---------------------------------------------------------------------------
# Create Gitea release from all platform artifacts
# ---------------------------------------------------------------------------
publish-release:
needs: [build-linux] # TODO: Add build-macos, build-windows when runners are available
runs-on: ubuntu-latest
env:
BUILD_TAG: ${{ github.ref_name || inputs.tag }}
NODE_EXTRA_CA_CERTS: /etc/ssl/certs/ca-certificates.crt
steps:
- name: Trust Cloudflare origin CA
run: |
apt-get update -qq
apt-get install -y --no-install-recommends ca-certificates
update-ca-certificates
- name: Download all artifacts
uses: https://git.kindred-systems.com/actions/download-artifact.git@v3
with:
path: artifacts
- name: List all release artifacts
run: |
echo "=== All release artifacts ==="
find artifacts -type f | sort
- name: Collect release files
run: |
mkdir -p release
find artifacts -type f \( \
-name "*.AppImage" -o \
-name "*.deb" -o \
-name "*.dmg" -o \
-name "*.7z" -o \
-name "*.exe" -o \
-name "*SHA256*" -o \
-name "*.sha256" \
\) -exec cp {} release/ \;
echo "=== Release files ==="
ls -lah release/
- name: Create release
env:
GITEA_TOKEN: ${{ secrets.RELEASE_TOKEN }}
GITEA_URL: ${{ github.server_url }}
REPO: ${{ github.repository }}
run: |
TAG="${BUILD_TAG}"
# Build JSON payload entirely in Python to avoid shell/Python type mismatches
PAYLOAD=$(python3 -c "
import json, re
tag = '${TAG}'
prerelease = bool(re.search(r'(rc|beta|alpha)', tag))
body = '''## Kindred Create {tag}
### Downloads
| Platform | File |
|----------|------|
| Linux (AppImage) | \`KindredCreate-*-Linux-x86_64.AppImage\` |
| Linux (Debian/Ubuntu) | \`kindred-create_*.deb\` |
*macOS and Windows builds are not yet available.*
SHA256 checksums are provided alongside each artifact.'''.format(tag=tag)
print(json.dumps({
'tag_name': tag,
'name': f'Kindred Create {tag}',
'body': body,
'prerelease': prerelease,
}))
")
# Delete existing release for this tag (if any) so we can recreate
existing=$(curl -s -o /dev/null -w "%{http_code}" \
-H "Authorization: token ${GITEA_TOKEN}" \
"${GITEA_URL}/api/v1/repos/${REPO}/releases/tags/${TAG}")
if [ "$existing" = "200" ]; then
release_id=$(curl -s \
-H "Authorization: token ${GITEA_TOKEN}" \
"${GITEA_URL}/api/v1/repos/${REPO}/releases/tags/${TAG}" | \
python3 -c "import sys,json; print(json.load(sys.stdin)['id'])")
curl -s -X DELETE \
-H "Authorization: token ${GITEA_TOKEN}" \
"${GITEA_URL}/api/v1/repos/${REPO}/releases/${release_id}"
echo "Deleted existing release ${release_id} for tag ${TAG}"
fi
# Create release
response=$(curl -s -w "\n%{http_code}" -X POST \
-H "Authorization: token ${GITEA_TOKEN}" \
-H "Content-Type: application/json" \
-d "$PAYLOAD" \
"${GITEA_URL}/api/v1/repos/${REPO}/releases")
http_code=$(echo "$response" | tail -1)
body=$(echo "$response" | sed '$d')
if [ "$http_code" -lt 200 ] || [ "$http_code" -ge 300 ]; then
echo "::error::Failed to create release (HTTP ${http_code}): ${body}"
exit 1
fi
release_id=$(echo "$body" | python3 -c "import sys,json; print(json.load(sys.stdin)['id'])")
echo "Created release ${release_id}"
# Upload assets
for file in release/*; do
filename=$(basename "$file")
echo "Uploading ${filename}..."
upload_resp=$(curl -s -w "\n%{http_code}" -X POST \
-H "Authorization: token ${GITEA_TOKEN}" \
-F "attachment=@${file}" \
"${GITEA_URL}/api/v1/repos/${REPO}/releases/${release_id}/assets?name=${filename}")
upload_code=$(echo "$upload_resp" | tail -1)
if [ "$upload_code" -lt 200 ] || [ "$upload_code" -ge 300 ]; then
echo "::warning::Failed to upload ${filename} (HTTP ${upload_code})"
else
echo " done."
fi
done

View File

@@ -0,0 +1,53 @@
name: Sync Silo Server Docs
on:
workflow_dispatch:
schedule:
- cron: "0 6 * * *" # Daily at 06:00 UTC as fallback
jobs:
sync:
runs-on: docs
steps:
- name: Checkout create repo
run: |
REPO_URL="http://gitea:3000/kindred/create.git"
if [ -d .git ]; then
git fetch "$REPO_URL" main
git checkout -f FETCH_HEAD
else
git clone --depth 1 --branch main "$REPO_URL" .
fi
- name: Clone Silo server docs
run: |
rm -rf /tmp/silo
git clone --depth 1 http://gitea:3000/kindred/silo.git /tmp/silo
mkdir -p docs/src/silo-server
cp /tmp/silo/docs/*.md docs/src/silo-server/
cp /tmp/silo/README.md docs/src/silo-server/overview.md
cp /tmp/silo/ROADMAP.md docs/src/silo-server/ROADMAP.md 2>/dev/null || true
cp /tmp/silo/frontend-spec.md docs/src/silo-server/frontend-spec.md 2>/dev/null || true
rm -rf /tmp/silo
- name: Check for changes
id: diff
run: |
git add docs/src/silo-server/
if git diff --cached --quiet; then
echo "changed=false" >> $GITHUB_OUTPUT
else
echo "changed=true" >> $GITHUB_OUTPUT
fi
- name: Commit and push
if: steps.diff.outputs.changed == 'true'
run: |
git config user.name "Kindred Bot"
git config user.email "bot@kindred-systems.com"
git commit -m "docs: sync Silo server documentation
Auto-synced from kindred/silo main branch."
PUSH_URL="http://kindred-bot:${{ secrets.RELEASE_TOKEN }}@gitea:3000/kindred/create.git"
git push "$PUSH_URL" HEAD:main