Files
create/.gitea/workflows/build.yml
forbes 5b7b770f80 fix(ci): use fixed path for ccache dir to survive workspace changes
The Gitea runner assigns a different workspace directory hash on each
run (e.g. /var/lib/gitea-runner/.cache/act/<hash>/hostexecutor/). When
CCACHE_DIR was set to ${{ github.workspace }}/.ccache, the actions/cache
save and restore operated on a path that changed every run, making the
restored cache land in the wrong location. This caused 0% hit rate on
the second build despite the cache being saved successfully.

Fix by using a fixed path (/tmp/ccache-kindred-create) for CCACHE_DIR
and the cache action path. CCACHE_BASEDIR remains set to the workspace
so ccache stores relative source paths, making cache entries portable
across different workspace directories.
2026-02-01 18:15:16 -06:00

231 lines
8.4 KiB
YAML

# 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: app-builder
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 }}
steps:
- name: Trust FreeIPA CA certificate
shell: bash
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
- name: Checkout repository
uses: https://github.com/actions/checkout@v4
with:
submodules: recursive
fetch-depth: 0
- name: Install pixi if needed
shell: bash
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
pixi --version
- name: Restore ccache
id: ccache-restore
uses: https://github.com/actions/cache/restore@v4
with:
path: /tmp/ccache-kindred-create
key: ccache-build-${{ github.ref_name }}-${{ github.sha }}
restore-keys: |
ccache-build-${{ github.ref_name }}-
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
- 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
- name: Save ccache
if: always()
uses: https://github.com/actions/cache/save@v4
with:
path: /tmp/ccache-kindred-create
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
- 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
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
- name: Upload build artifact
uses: https://github.com/actions/upload-artifact@v3
with:
name: ${{ env.ARTIFACT_NAME }}
path: |
build/release/*.tar.xz
build/release/*.deb
build/release/*.sha256
retention-days: 30