From ba9309f6da9770ba89702a6df6fcb9cdd3d3069d Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 2 Nov 2025 00:23:59 +0000 Subject: [PATCH 01/22] Initial plan From 70461934f2f25cc58ad1ac6e79da83267251031e Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 2 Nov 2025 00:27:00 +0000 Subject: [PATCH 02/22] Add test-build.yml workflow for testing build process Co-authored-by: CJFWeatherhead <6923098+CJFWeatherhead@users.noreply.github.com> --- .github/workflows/test-build.yml | 414 +++++++++++++++++++++++++++++++ 1 file changed, 414 insertions(+) create mode 100644 .github/workflows/test-build.yml diff --git a/.github/workflows/test-build.yml b/.github/workflows/test-build.yml new file mode 100644 index 0000000..65f4b7e --- /dev/null +++ b/.github/workflows/test-build.yml @@ -0,0 +1,414 @@ +name: Test Build + +on: + # Manual trigger for testing + workflow_dispatch: + + # Trigger on push to this branch for iterative testing + push: + branches: + - copilot/duplicate-workflow-discard-artifacts + +jobs: + test: + name: Run Unit Tests + runs-on: ubuntu-latest + permissions: + contents: read + + steps: + - name: Checkout code + uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Set up Python + uses: actions/setup-python@v5 + with: + python-version: '3.12' + cache: 'pip' + + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install -r requirements.txt + + - name: Run unit tests + run: | + python -m unittest discover -s tests -v + + build-linux: + name: Build Linux ${{ matrix.arch }} + needs: test + runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + arch: [x86_64, i686, arm64] + + permissions: + contents: read + + steps: + - name: Checkout code + uses: actions/checkout@v4 + with: + fetch-depth: 0 + - name: Fetch all tags + run: git fetch --tags --force + + - name: Set up QEMU for ARM64 emulation + if: matrix.arch == 'arm64' + uses: docker/setup-qemu-action@v3 + with: + platforms: linux/arm64 + + - name: Set up Docker Buildx + if: matrix.arch == 'arm64' || matrix.arch == 'i686' + uses: docker/setup-buildx-action@v3 + + - name: Calculate version + id: version + shell: bash + run: | + # Use test version for test builds + VERSION="test-$(date +%Y%m%d-%H%M%S)" + echo "version=${VERSION}" >> "$GITHUB_OUTPUT" + echo "Generated version: ${VERSION}" + + - name: Set up Python + uses: actions/setup-python@v5 + with: + python-version: '3.12' + cache: 'pip' + + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install -r requirements.txt + + - name: Update version in files + run: | + VERSION="${{ steps.version.outputs.version }}" + python3 -c " + import re + version = '$VERSION' + with open('chatrixcd/__init__.py', 'r') as f: + content = f.read() + content = re.sub(r'__version__ = \".*\"', f'__version__ = \"{version}\"', content) + with open('chatrixcd/__init__.py', 'w') as f: + f.write(content) + print(f'Updated version to {version}') + " + + - name: Build with Nuitka (x86_64) + if: matrix.arch == 'x86_64' + uses: Nuitka/Nuitka-Action@main + with: + nuitka-version: main + script-name: chatrixcd/main.py + mode: onefile + output-file: chatrixcd-linux-x86_64 + enable-plugins: anti-bloat + assume-yes-for-downloads: true + linux-icon: assets/icon.png + include-data-dir: assets=assets + + - name: Build with Nuitka (i686 - using Docker) + if: matrix.arch == 'i686' + run: | + docker run --rm -v "$PWD":/src -w /src i386/python:3.12-slim sh -c " + apt-get update && apt-get install -y gcc patchelf ccache && + pip install --upgrade pip && + pip install -r requirements.txt && + pip install nuitka ordered-set && + python -m nuitka --mode=onefile \ + --output-filename=chatrixcd-linux-i686 \ + --enable-plugin=anti-bloat \ + --assume-yes-for-downloads \ + --linux-icon=assets/icon.png \ + --include-data-dir=assets=assets \ + chatrixcd/main.py + " + + - name: Build with Nuitka (arm64 - using Docker) + if: matrix.arch == 'arm64' + run: | + docker run --rm --platform linux/arm64 -v "$PWD":/src -w /src arm64v8/python:3.12-slim sh -c " + apt-get update && apt-get install -y gcc patchelf ccache && + pip install --upgrade pip && + pip install -r requirements.txt && + pip install nuitka ordered-set && + python -m nuitka --mode=onefile \ + --output-filename=chatrixcd-linux-arm64 \ + --enable-plugin=anti-bloat \ + --assume-yes-for-downloads \ + --linux-icon=assets/icon.png \ + --include-data-dir=assets=assets \ + chatrixcd/main.py + " + + - name: Verify build and get checksum + run: | + BINARY="chatrixcd-linux-${{ matrix.arch }}" + if [ -f "$BINARY" ]; then + echo "✅ Build successful for ${{ matrix.arch }}" + ls -lh "$BINARY" + sha256sum "$BINARY" + echo "---" + echo "Size: $(stat -c%s "$BINARY") bytes" + echo "SHA256: $(sha256sum "$BINARY" | awk '{print $1}')" + else + echo "❌ Build failed - binary not found" + exit 1 + fi + + build-windows: + name: Build Windows ${{ matrix.arch }} + needs: test + runs-on: windows-latest + strategy: + fail-fast: false + matrix: + arch: [x86_64] + + permissions: + contents: read + + steps: + - name: Checkout code + uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Fetch all tags + run: git fetch --tags --force + + - name: Calculate version + id: version + shell: bash + run: | + # Use test version for test builds + VERSION="test-$(date +%Y%m%d-%H%M%S)" + echo "version=${VERSION}" >> "$GITHUB_OUTPUT" + echo "Generated version: ${VERSION}" + + - name: Set up Python + uses: actions/setup-python@v5 + with: + python-version: '3.12' + cache: 'pip' + + - name: Setup CMake + uses: lukka/get-cmake@latest + + - name: Install libolm (Windows) + shell: pwsh + run: | + # Download and build libolm (pinned to v3.2.16 for reproducible builds) + git clone --branch 3.2.16 --depth 1 https://gitlab.matrix.org/matrix-org/olm.git C:\olm + cd C:\olm + + # Patch CMakeLists.txt to require CMake 3.5+ (for compatibility with modern CMake) + $originalContent = Get-Content CMakeLists.txt -Raw + $patchedContent = $originalContent -replace 'cmake_minimum_required\(VERSION [0-9]+\.[0-9]+(?:\.[0-9]+)?\)', 'cmake_minimum_required(VERSION 3.5)' + if ($patchedContent -ne $originalContent) { + Set-Content CMakeLists.txt $patchedContent + Write-Host "Successfully patched CMakeLists.txt to require CMake 3.5+" + } else { + Write-Host "Warning: CMakeLists.txt patch pattern not found, continuing anyway..." + } + + cmake -S . -B build ` + -DCMAKE_INSTALL_PREFIX=C:\olm-install ` + -DCMAKE_BUILD_TYPE=Release ` + -DBUILD_SHARED_LIBS=OFF + cmake --build build --config Release + cmake --install build --config Release + + # Debug: Show what files were created + Write-Host "Contents of C:\olm-install\lib:" + Get-ChildItem -Path C:\olm-install\lib -Recurse + + # python-olm expects olm.lib, but CMake creates olm_static.lib when BUILD_SHARED_LIBS=OFF + # Copy the static library with the expected name + if (Test-Path "C:\olm-install\lib\olm_static.lib") { + Copy-Item "C:\olm-install\lib\olm_static.lib" "C:\olm-install\lib\olm.lib" + Write-Host "Copied olm_static.lib to olm.lib" + } else { + Write-Error "ERROR: olm_static.lib not found in C:\olm-install\lib. Build cannot continue." + exit 1 + } + + # Set environment variables for python-olm build + # Include both the include and lib paths, and also set CMAKE_PREFIX_PATH for FindOlm + echo "INCLUDE=C:\olm-install\include;$env:INCLUDE" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append + echo "LIB=C:\olm-install\lib;$env:LIB" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append + echo "CMAKE_PREFIX_PATH=C:\olm-install;$env:CMAKE_PREFIX_PATH" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append + + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install -r requirements.txt + + - name: Update version in files + shell: bash + run: | + VERSION="${{ steps.version.outputs.version }}" + python3 -c " + import re + version = '$VERSION' + with open('chatrixcd/__init__.py', 'r') as f: + content = f.read() + content = re.sub(r'__version__ = \".*\"', f'__version__ = \"{version}\"', content) + with open('chatrixcd/__init__.py', 'w') as f: + f.write(content) + print(f'Updated version to {version}') + " + + - name: Build with Nuitka + uses: Nuitka/Nuitka-Action@main + with: + nuitka-version: main + script-name: chatrixcd/main.py + mode: onefile + output-file: chatrixcd-windows-${{ matrix.arch }}.exe + enable-plugins: anti-bloat + assume-yes-for-downloads: true + company-name: "ChatrixCD Contributors" + product-name: "ChatrixCD" + file-version: ${{ steps.version.outputs.version }} + product-version: ${{ steps.version.outputs.version }} + file-description: "Matrix bot for CI/CD automation with Semaphore UI" + copyright: "Copyright (c) 2024 ChatrixCD Contributors" + windows-icon-from-ico: assets/icon.ico + onefile-tempdir-spec: "%TEMP%\\chatrixcd" + windows-console-mode: force + include-data-dir: assets=assets + + - name: Verify build and get checksum + shell: bash + run: | + BINARY="chatrixcd-windows-${{ matrix.arch }}.exe" + if [ -f "$BINARY" ]; then + echo "✅ Build successful for ${{ matrix.arch }}" + ls -lh "$BINARY" + sha256sum "$BINARY" + echo "---" + echo "Size: $(stat -c%s "$BINARY") bytes" + echo "SHA256: $(sha256sum "$BINARY" | awk '{print $1}')" + else + echo "❌ Build failed - binary not found" + exit 1 + fi + + build-macos: + name: Build macOS Universal + needs: test + runs-on: macos-latest + + permissions: + contents: read + + steps: + - name: Checkout code + uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Fetch all tags + run: git fetch --tags --force + + - name: Calculate version + id: version + shell: bash + run: | + # Use test version for test builds + VERSION="test-$(date +%Y%m%d-%H%M%S)" + echo "version=${VERSION}" >> "$GITHUB_OUTPUT" + echo "Generated version: ${VERSION}" + + - name: Set up Python + uses: actions/setup-python@v5 + with: + python-version: '3.12' + cache: 'pip' + + - name: Install build dependencies (macOS) + run: | + # Install libolm and cmake from homebrew to avoid building from source + brew install libolm pkg-config cmake + + - name: Set PKG_CONFIG_PATH for subsequent steps + run: | + # Detect homebrew prefix (Apple Silicon uses /opt/homebrew, Intel uses /usr/local) + HOMEBREW_PREFIX=$(brew --prefix) + + # Set environment variables for subsequent steps + { + echo "PKG_CONFIG_PATH=${HOMEBREW_PREFIX}/lib/pkgconfig:${PKG_CONFIG_PATH}" + echo "CFLAGS=-I${HOMEBREW_PREFIX}/include" + echo "LDFLAGS=-L${HOMEBREW_PREFIX}/lib" + } >> "$GITHUB_ENV" + + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install -r requirements.txt + + - name: Update version in files + run: | + VERSION="${{ steps.version.outputs.version }}" + python3 -c " + import re + version = '$VERSION' + with open('chatrixcd/__init__.py', 'r') as f: + content = f.read() + content = re.sub(r'__version__ = \".*\"', f'__version__ = \"{version}\"', content) + with open('chatrixcd/__init__.py', 'w') as f: + f.write(content) + print(f'Updated version to {version}') + " + + - name: Build with Nuitka + uses: Nuitka/Nuitka-Action@main + with: + nuitka-version: main + script-name: chatrixcd/main.py + mode: onefile + output-file: chatrixcd-macos-universal + enable-plugins: anti-bloat + assume-yes-for-downloads: true + macos-create-app-bundle: true + macos-app-icon: assets/icon.png + macos-app-name: "ChatrixCD" + macos-app-version: ${{ steps.version.outputs.version }} + macos-target-arch: universal2 + include-data-dir: assets=assets + + - name: Verify build and get checksum + run: | + # Check for binary + BINARY="chatrixcd-macos-universal" + if [ -f "$BINARY" ]; then + echo "✅ Binary build successful" + ls -lh "$BINARY" + shasum -a 256 "$BINARY" + echo "---" + echo "Binary Size: $(stat -f%z "$BINARY") bytes" + echo "Binary SHA256: $(shasum -a 256 "$BINARY" | awk '{print $1}')" + else + echo "⚠️ Binary not found, checking for app bundle only" + fi + + # Check for app bundle + if [ -d "ChatrixCD.app" ]; then + echo "✅ App bundle build successful" + du -sh ChatrixCD.app + find ChatrixCD.app -type f -exec shasum -a 256 {} \; | head -10 + echo "---" + echo "App bundle created successfully" + else + echo "❌ Build failed - neither binary nor app bundle found" + exit 1 + fi From 5ba28362f8eb7abd00fa7f9aae85bdcf5a2fc7b7 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 2 Nov 2025 00:33:12 +0000 Subject: [PATCH 03/22] Add workflow test status documentation Co-authored-by: CJFWeatherhead <6923098+CJFWeatherhead@users.noreply.github.com> --- WORKFLOW_TEST_STATUS.md | 103 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 103 insertions(+) create mode 100644 WORKFLOW_TEST_STATUS.md diff --git a/WORKFLOW_TEST_STATUS.md b/WORKFLOW_TEST_STATUS.md new file mode 100644 index 0000000..412b0fe --- /dev/null +++ b/WORKFLOW_TEST_STATUS.md @@ -0,0 +1,103 @@ +# Test Build Workflow Status + +## Overview +A test build workflow (`test-build.yml`) has been created to validate the build process before merging changes into the main `build.yml` workflow. + +## Workflow Configuration + +### Key Differences from Production `build.yml`: +1. **Triggers**: + - Push to `copilot/duplicate-workflow-discard-artifacts` branch + - Manual workflow_dispatch + +2. **No Artifact Publishing**: + - Removed all `upload-artifact` steps + - Removed entire `release` job + - Artifacts are discarded after builds complete + +3. **Test Versioning**: + - Uses test version format: `test-YYYYMMDD-HHMMSS` + - Does not modify git tags or create releases + +4. **Verification Steps**: + - Added checksum generation (SHA256) for each binary + - Added file size reporting + - Validates that binaries were actually created + +## Build Matrix + +The test workflow builds for all required platforms: + +### Linux +- x86_64 (native Nuitka) +- i686 (Docker-based with i386/python:3.12-slim) +- arm64 (Docker-based with arm64v8/python:3.12-slim, uses QEMU emulation) + +### Windows +- x86_64 (native with libolm build from source) + +### macOS +- universal2 (native with homebrew libolm, creates both binary and .app bundle) + +## Expected Outputs + +When the workflow completes successfully, each build job will output: + +### For Linux and Windows: +``` +✅ Build successful for +-rw-r--r-- 1 runner runner