chore: migrate submodules to public repos, rework docs and CI/CD
Some checks failed
Build and Test / build (push) Has been cancelled

- Update .gitmodules: ztools, silo, and OndselSolver now reference
  public git.kindred-systems.com URLs instead of internal Gitea
- Merge OndselSolver numerical solver with ML solver scaffolding
  into unified kindred/solver repository
- Rewrite README.md for conciseness
- Add docs/CI_CD.md with full pipeline documentation
- Rework CI/CD workflows for public dockerized runners
- Add multi-platform release builds (Linux, macOS, Windows)
- Release workflow triggers on v* tags only
- Update docs/REPOSITORY_STATE.md and docs/INTEGRATION_PLAN.md
This commit is contained in:
2026-02-03 10:54:47 -06:00
parent 0ef9ffcf51
commit 1b3f780aa1
8 changed files with 877 additions and 1103 deletions

View File

@@ -10,7 +10,10 @@ on:
jobs:
build:
runs-on: app-builder
runs-on: ubuntu-latest
container:
image: ubuntu:24.04
options: --security-opt seccomp=unconfined
env:
CCACHE_DIR: /tmp/ccache-kindred-create
@@ -19,35 +22,16 @@ jobs:
CCACHE_MAXSIZE: "4G"
CCACHE_SLOPPINESS: "include_file_ctime,include_file_mtime,pch_defines,time_macros"
CCACHE_BASEDIR: ${{ github.workspace }}
DEBIAN_FRONTEND: noninteractive
steps:
- name: Trust FreeIPA CA certificate
shell: bash
- name: Install system prerequisites
run: |
# Download and install the FreeIPA CA certificate for SSL verification
echo "Downloading FreeIPA CA certificate..."
curl -fsSL -o /tmp/ipa-ca.crt https://ipa.kindred.internal/ipa/config/ca.crt
# Verify the certificate is valid (just show subject and dates)
echo "Verifying certificate..."
openssl x509 -in /tmp/ipa-ca.crt -subject -dates -noout
# Set NODE_EXTRA_CA_CERTS for Node.js-based actions (used by upload-artifact)
echo "NODE_EXTRA_CA_CERTS=/tmp/ipa-ca.crt" >> $GITHUB_ENV
# Verify SSL connection to Gitea works with the CA cert
echo "Testing SSL connection to Gitea..."
curl -fsSL --cacert /tmp/ipa-ca.crt https://gitea.kindred.internal/api/v1/version
echo ""
echo "SSL certificate setup complete"
- name: Install node if needed
shell: bash
run: |
if ! command -v node &> /dev/null; then
curl -fsSL https://nodejs.org/dist/v20.18.0/node-v20.18.0-linux-x64.tar.xz | sudo tar -xJ -C /usr/local --strip-components=1
fi
node --version
apt-get update -qq
apt-get install -y --no-install-recommends \
ca-certificates curl git xvfb xauth openssl \
libgl1-mesa-dev libglu1-mesa-dev libx11-dev libxkbcommon-dev \
libxcb-xkb-dev libfontconfig1-dev
- name: Checkout repository
uses: https://github.com/actions/checkout@v4
@@ -55,14 +39,11 @@ jobs:
submodules: recursive
fetch-depth: 0
- name: Install pixi if needed
shell: bash
- name: Install pixi
run: |
if ! command -v pixi &> /dev/null; then
curl -fsSL https://pixi.sh/install.sh | bash
echo "$HOME/.pixi/bin" >> $GITHUB_PATH
export PATH="$HOME/.pixi/bin:$PATH"
fi
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
@@ -76,32 +57,18 @@ jobs:
ccache-build-main-
- name: Prepare ccache
shell: bash
run: |
mkdir -p $CCACHE_DIR
pixi run ccache -z
echo "=== ccache configuration ==="
pixi run ccache -p
echo ""
echo "=== ccache status before build ==="
pixi run ccache -s
- name: Configure (CMake)
shell: bash
run: |
pixi run cmake --preset conda-linux-release
run: pixi run cmake --preset conda-linux-release
- name: Build
run: pixi run cmake --build build/release -j$(nproc)
- name: Show ccache statistics
shell: bash
run: |
echo "=== ccache statistics after build ==="
pixi run ccache -s
echo ""
echo "=== ccache cache directory size ==="
du -sh $CCACHE_DIR
run: pixi run ccache -s
- name: Save ccache
if: always()
@@ -111,30 +78,18 @@ jobs:
key: ccache-build-${{ github.ref_name }}-${{ github.sha }}
- name: Run C++ unit tests
shell: bash
continue-on-error: true
timeout-minutes: 15
run: |
# Set discovery timeout to prevent hangs during test enumeration
export CTEST_DISCOVERY_TIMEOUT=60
# Use xvfb for tests that require a display (Qt GUI tests)
# Exclude Assembly tests which hang during discovery
pixi run xvfb-run -a ctest --test-dir build/release \
--output-on-failure \
--timeout 120 \
--exclude-regex "Assembly_tests" \
2>&1 || true
echo ""
echo "=== Test Summary ==="
echo "Note: Assembly_tests excluded due to discovery timeout issues"
cat build/release/Testing/Temporary/LastTestsFailed.log 2>/dev/null || echo "All included tests passed (or no failures logged)"
- name: Install
run: |
# Install to a custom prefix for packaging
pixi run cmake --install build/release --prefix build/release/install
run: pixi run cmake --install build/release --prefix build/release/install
- name: Run Python CLI tests
timeout-minutes: 10
@@ -145,79 +100,13 @@ jobs:
run: pixi run timeout 300 xvfb-run -a build/release/bin/FreeCAD -t 0 || true
- name: Package build artifacts
shell: bash
run: |
# Create a distributable tarball from the installed build
ARTIFACT_NAME="kindred-create-$(git describe --tags --always)-linux-x86_64"
echo "Creating artifact: ${ARTIFACT_NAME}"
# The install step puts files in build/release/install
cd build/release
if [ -d "install" ]; then
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
ls -lh "${ARTIFACT_NAME}.tar.xz"
else
echo "ERROR: install directory not found"
ls -la
exit 1
fi
- name: Prepare bundled environment for .deb
shell: bash
run: |
# Create a bundled environment with all dependencies (like AppImage)
# The .deb needs all libraries bundled since we can't rely on system packages
# We need BOTH the pixi environment (dependencies) AND the built FreeCAD
BUNDLE_DIR="build/release/bundle"
mkdir -p "${BUNDLE_DIR}"
echo "Copying pixi environment (dependencies)..."
cp -a .pixi/envs/default/* "${BUNDLE_DIR}/"
echo "After pixi copy: $(du -sh ${BUNDLE_DIR} | cut -f1)"
echo "Copying built FreeCAD into bundle..."
# Copy the built FreeCAD (bin, lib, Mod, share, etc.) over the pixi env
cp -a build/release/install/* "${BUNDLE_DIR}/"
echo "After FreeCAD copy: $(du -sh ${BUNDLE_DIR} | cut -f1)"
# Remove unnecessary files to reduce size significantly
echo "Removing unnecessary files..."
rm -rf "${BUNDLE_DIR}/include"
rm -rf "${BUNDLE_DIR}/conda-meta"
rm -rf "${BUNDLE_DIR}/doc"
rm -rf "${BUNDLE_DIR}/man"
rm -rf "${BUNDLE_DIR}/share/doc"
rm -rf "${BUNDLE_DIR}/share/man"
rm -rf "${BUNDLE_DIR}/share/gtk-doc"
rm -rf "${BUNDLE_DIR}/share/info"
rm -rf "${BUNDLE_DIR}/lib/cmake"
rm -rf "${BUNDLE_DIR}/lib/pkgconfig"
rm -rf "${BUNDLE_DIR}/share/pkgconfig"
# Remove static libraries and dev files
find "${BUNDLE_DIR}" -name "*.a" -delete 2>/dev/null || true
find "${BUNDLE_DIR}" -name "*.la" -delete 2>/dev/null || true
find "${BUNDLE_DIR}" -name "*.cmake" -delete 2>/dev/null || true
find "${BUNDLE_DIR}" -path "*/__pycache__/*" -delete 2>/dev/null || true
find "${BUNDLE_DIR}" -name "*.pyc" -delete 2>/dev/null || true
find "${BUNDLE_DIR}" -name "*.pyo" -delete 2>/dev/null || true
# List key binaries to verify FreeCAD is there
echo "Key binaries in bundle:"
ls -la "${BUNDLE_DIR}/bin/FreeCAD" "${BUNDLE_DIR}/bin/FreeCADCmd" 2>/dev/null || echo "FreeCAD binaries not found!"
echo "Final bundle size: $(du -sh ${BUNDLE_DIR} | cut -f1)"
- name: Build .deb package
shell: bash
run: |
# Build .deb package from bundled environment
# The build-deb.sh script handles version conversion to Debian format
# (e.g., weekly-2025.01.28 -> 0~weekly.2025.01.28)
./package/debian/build-deb.sh build/release/bundle 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://github.com/actions/upload-artifact@v3
@@ -225,6 +114,5 @@ jobs:
name: ${{ env.ARTIFACT_NAME }}
path: |
build/release/*.tar.xz
build/release/*.deb
build/release/*.sha256
retention-days: 30
retention-days: 14

View File

@@ -3,17 +3,23 @@ name: Release Build
on:
push:
tags: ["v*", "weekly-*"]
tags: ["v*"]
workflow_dispatch:
inputs:
tag:
description: "Release tag (e.g., v1.0.0)"
description: "Release tag (e.g., v0.1.0)"
required: true
type: string
jobs:
build-linux-appimage:
runs-on: app-builder
# ---------------------------------------------------------------------------
# Linux: AppImage + .deb
# ---------------------------------------------------------------------------
build-linux:
runs-on: ubuntu-latest
container:
image: ubuntu:24.04
options: --security-opt seccomp=unconfined
env:
CCACHE_DIR: /tmp/ccache-kindred-create
@@ -23,38 +29,18 @@ jobs:
CCACHE_SLOPPINESS: "include_file_ctime,include_file_mtime,pch_defines,time_macros"
CCACHE_BASEDIR: ${{ github.workspace }}
BUILD_TAG: ${{ github.ref_name || inputs.tag }}
MAKE_INSTALLER: "true"
CFLAGS: "-O3"
CXXFLAGS: "-O3"
DEBIAN_FRONTEND: noninteractive
steps:
- name: Trust FreeIPA CA certificate
shell: bash
- name: Install system prerequisites
run: |
# Download and install the FreeIPA CA certificate for SSL verification
echo "Downloading FreeIPA CA certificate..."
curl -fsSL -o /tmp/ipa-ca.crt https://ipa.kindred.internal/ipa/config/ca.crt
# Verify the certificate is valid (just show subject and dates)
echo "Verifying certificate..."
openssl x509 -in /tmp/ipa-ca.crt -subject -dates -noout
# Set NODE_EXTRA_CA_CERTS for Node.js-based actions (used by upload-artifact)
echo "NODE_EXTRA_CA_CERTS=/tmp/ipa-ca.crt" >> $GITHUB_ENV
# Verify SSL connection to Gitea works with the CA cert
echo "Testing SSL connection to Gitea..."
curl -fsSL --cacert /tmp/ipa-ca.crt https://gitea.kindred.internal/api/v1/version
echo ""
echo "SSL certificate setup complete"
- name: Install node if needed
shell: bash
run: |
if ! command -v node &> /dev/null; then
curl -fsSL https://nodejs.org/dist/v20.18.0/node-v20.18.0-linux-x64.tar.xz | sudo tar -xJ -C /usr/local --strip-components=1
fi
node --version
apt-get update -qq
apt-get install -y --no-install-recommends \
ca-certificates curl git file fuse3 xvfb xauth openssl dpkg-dev \
libgl1-mesa-dev libglu1-mesa-dev libx11-dev libxkbcommon-dev \
libxcb-xkb-dev libfontconfig1-dev
- name: Checkout repository
uses: https://github.com/actions/checkout@v4
@@ -63,14 +49,11 @@ jobs:
fetch-depth: 0
fetch-tags: true
- name: Install pixi if needed
shell: bash
- name: Install pixi
run: |
if ! command -v pixi &> /dev/null; then
curl -fsSL https://pixi.sh/install.sh | bash
echo "$HOME/.pixi/bin" >> $GITHUB_PATH
export PATH="$HOME/.pixi/bin:$PATH"
fi
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
@@ -78,24 +61,15 @@ jobs:
uses: https://github.com/actions/cache/restore@v4
with:
path: /tmp/ccache-kindred-create
key: ccache-release-${{ github.ref_name }}-${{ github.sha }}
key: ccache-release-linux-${{ github.sha }}
restore-keys: |
ccache-release-
ccache-release-linux-
ccache-build-main-
- name: Prepare ccache
shell: bash
run: |
mkdir -p $CCACHE_DIR
pixi run ccache -z
echo "=== ccache configuration ==="
pixi run ccache -p
echo ""
echo "=== ccache status before build ==="
pixi run ccache -s
- name: Write version info
run: python3 package/scripts/write_version_info.py ../freecad_version.txt
- name: Build release package (AppImage)
working-directory: package/rattler-build
@@ -104,54 +78,267 @@ jobs:
pixi run -e package create_bundle
- name: Show ccache statistics
shell: bash
run: |
echo "=== ccache statistics after build ==="
pixi run ccache -s
echo ""
echo "=== ccache cache directory size ==="
du -sh $CCACHE_DIR
run: pixi run ccache -s
- name: Save ccache
if: always()
uses: https://github.com/actions/cache/save@v4
with:
path: /tmp/ccache-kindred-create
key: ccache-release-${{ github.ref_name }}-${{ github.sha }}
key: ccache-release-linux-${{ github.sha }}
- name: Build .deb package
shell: bash
run: |
# Build .deb package from the AppDir used for AppImage
# The build-deb.sh script handles version conversion to Debian format
# (e.g., weekly-2025.01.28 -> 0~weekly.2025.01.28)
./package/debian/build-deb.sh \
package/rattler-build/linux/AppDir/usr \
package/rattler-build/linux \
"${BUILD_TAG}"
- name: List built artifacts
shell: bash
run: |
echo "Built artifacts:"
ls -lah package/rattler-build/linux/*.AppImage* 2>/dev/null || echo "No AppImage files found"
ls -lah package/rattler-build/linux/*.deb* 2>/dev/null || echo "No .deb files found"
ls -lah package/rattler-build/linux/*-SHA256.txt 2>/dev/null || echo "No SHA256 files found"
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 AppImage artifact
- name: Upload Linux artifacts
uses: https://github.com/actions/upload-artifact@v3
with:
name: kindred-create-appimage
name: release-linux
path: |
package/rattler-build/linux/*.AppImage
package/rattler-build/linux/*.deb
package/rattler-build/linux/*-SHA256.txt
package/rattler-build/linux/*.sha256
if-no-files-found: error
- name: Upload .deb artifact
# ---------------------------------------------------------------------------
# macOS: DMG (Intel + Apple Silicon)
# ---------------------------------------------------------------------------
build-macos:
strategy:
matrix:
include:
- runner: macos-13
arch: x86_64
preset: conda-macos-release
- runner: macos-14
arch: arm64
preset: conda-macos-release
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://github.com/actions/checkout@v4
with:
submodules: recursive
fetch-depth: 0
fetch-tags: true
- 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://github.com/actions/cache/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://github.com/actions/cache/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://github.com/actions/upload-artifact@v3
with:
name: kindred-create-deb
name: release-macos-${{ matrix.arch }}
path: |
package/rattler-build/linux/*.deb
package/rattler-build/linux/*.deb.sha256
if-no-files-found: warn
package/rattler-build/osx/*.dmg
package/rattler-build/osx/*-SHA256.txt
if-no-files-found: error
# ---------------------------------------------------------------------------
# Windows: .exe installer + .7z archive
# ---------------------------------------------------------------------------
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://github.com/actions/checkout@v4
with:
submodules: recursive
fetch-depth: 0
fetch-tags: true
- 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://github.com/actions/cache/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: Build NSIS installer
shell: bash
working-directory: package/rattler-build/windows
run: |
if [ "${MAKE_INSTALLER}" == "true" ]; then
# The create_bundle.sh script builds the 7z archive.
# NSIS installer is built as part of the bundle script when
# MAKE_INSTALLER is set and NSIS is available.
echo "Installer build completed as part of create_bundle"
fi
- name: Save ccache
if: always()
uses: https://github.com/actions/cache/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://github.com/actions/upload-artifact@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, build-macos, build-windows]
runs-on: ubuntu-latest
env:
BUILD_TAG: ${{ github.ref_name || inputs.tag }}
steps:
- name: Download all artifacts
uses: https://github.com/actions/download-artifact@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
uses: https://gitea.com/actions/release-action@main
with:
files: release/*
title: "Kindred Create ${{ env.BUILD_TAG }}"
body: |
## Kindred Create ${{ env.BUILD_TAG }}
### Downloads
| Platform | File |
|----------|------|
| Linux (AppImage) | `KindredCreate-*-Linux-x86_64.AppImage` |
| Linux (Debian/Ubuntu) | `kindred-create_*.deb` |
| macOS (Intel) | `KindredCreate-*-macOS-x86_64.dmg` |
| macOS (Apple Silicon) | `KindredCreate-*-macOS-arm64.dmg` |
| Windows (Installer) | `KindredCreate-*-Windows-x86_64-installer.exe` |
| Windows (Portable) | `KindredCreate-*-Windows-x86_64.7z` |
SHA256 checksums are provided alongside each artifact.
prerelease: ${{ contains(github.ref_name, 'rc') || contains(github.ref_name, 'beta') || contains(github.ref_name, 'alpha') }}
api_key: ${{ secrets.RELEASE_TOKEN }}