chore: initialize project scaffold with meson build system, CI workflow, config, and source stubs
This commit is contained in:
@@ -0,0 +1,558 @@
|
||||
name: RT Terminal CI
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
- master
|
||||
- develop
|
||||
- 'feature/**'
|
||||
- 'release/**'
|
||||
- 'hotfix/**'
|
||||
paths-ignore:
|
||||
- '**.md'
|
||||
- 'LICENSE'
|
||||
- '.gitignore'
|
||||
- 'docs/**'
|
||||
pull_request:
|
||||
branches:
|
||||
- main
|
||||
- master
|
||||
- develop
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
build_type:
|
||||
description: 'Build type'
|
||||
required: false
|
||||
default: 'release'
|
||||
type: choice
|
||||
options:
|
||||
- release
|
||||
- debug
|
||||
|
||||
env:
|
||||
PROJECT_NAME: rt
|
||||
BUILD_TYPE: ${{ github.event.inputs.build_type || 'release' }}
|
||||
|
||||
jobs:
|
||||
lint:
|
||||
name: Code Quality
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y cppcheck clang-format
|
||||
|
||||
- name: Run cppcheck
|
||||
run: |
|
||||
cppcheck --enable=all \
|
||||
--suppress=missingIncludeSystem \
|
||||
--suppress=unusedFunction \
|
||||
--suppress=unmatchedSuppression \
|
||||
--error-exitcode=1 \
|
||||
--inline-suppr \
|
||||
--xml --xml-version=2 \
|
||||
src/ 2> cppcheck-report.xml || true
|
||||
cppcheck --enable=all \
|
||||
--suppress=missingIncludeSystem \
|
||||
--suppress=unusedFunction \
|
||||
--suppress=unmatchedSuppression \
|
||||
--error-exitcode=1 \
|
||||
src/
|
||||
|
||||
- name: Check code formatting
|
||||
run: |
|
||||
find src/ -name '*.c' -o -name '*.h' | xargs clang-format --dry-run --Werror || {
|
||||
echo "Code formatting issues found. Run 'make format' to fix."
|
||||
exit 1
|
||||
}
|
||||
|
||||
- name: Upload cppcheck report
|
||||
uses: actions/upload-artifact@v4
|
||||
if: always()
|
||||
with:
|
||||
name: cppcheck-report
|
||||
path: cppcheck-report.xml
|
||||
retention-days: 30
|
||||
|
||||
build-matrix:
|
||||
name: Build (${{ matrix.os }}, ${{ matrix.build_type }})
|
||||
runs-on: ${{ matrix.os }}
|
||||
needs: lint
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os: [ubuntu-latest, ubuntu-22.04]
|
||||
build_type: [release, debug]
|
||||
include:
|
||||
- os: ubuntu-latest
|
||||
pkg_manager: apt-get
|
||||
- os: ubuntu-22.04
|
||||
pkg_manager: apt-get
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Cache dependencies
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: |
|
||||
~/.cache/pip
|
||||
/var/cache/apt/archives
|
||||
key: ${{ runner.os }}-deps-${{ hashFiles('meson.build') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-deps-
|
||||
|
||||
- name: Install system dependencies
|
||||
run: |
|
||||
sudo ${{ matrix.pkg_manager }} update
|
||||
sudo ${{ matrix.pkg_manager }} install -y \
|
||||
build-essential \
|
||||
meson \
|
||||
ninja-build \
|
||||
pkg-config \
|
||||
libgtk-4-dev \
|
||||
libvte-2.91-gtk4-dev \
|
||||
libfreetype-dev \
|
||||
libpango1.0-dev \
|
||||
libcairo2-dev
|
||||
|
||||
- name: Verify dependencies
|
||||
run: |
|
||||
echo "==> Checking pkg-config dependencies..."
|
||||
pkg-config --exists gtk4 || exit 1
|
||||
pkg-config --exists vte-2.91-gtk4 || exit 1
|
||||
pkg-config --exists freetype2 || exit 1
|
||||
pkg-config --exists pango || exit 1
|
||||
pkg-config --exists cairo || exit 1
|
||||
echo "==> All dependencies satisfied"
|
||||
echo ""
|
||||
echo "==> Dependency versions:"
|
||||
echo "GTK4: $(pkg-config --modversion gtk4)"
|
||||
echo "VTE: $(pkg-config --modversion vte-2.91-gtk4)"
|
||||
echo "FreeType: $(pkg-config --modversion freetype2)"
|
||||
echo "Pango: $(pkg-config --modversion pango)"
|
||||
echo "Cairo: $(pkg-config --modversion cairo)"
|
||||
|
||||
- name: Configure build
|
||||
run: |
|
||||
meson setup build \
|
||||
--buildtype=${{ matrix.build_type }} \
|
||||
--prefix=/usr \
|
||||
-Denable_debug_logging=${{ matrix.build_type == 'debug' && 'true' || 'false' }}
|
||||
|
||||
- name: Build project
|
||||
run: |
|
||||
meson compile -C build -v
|
||||
|
||||
- name: Verify build artifacts
|
||||
run: |
|
||||
test -f build/${{ env.PROJECT_NAME }} || exit 1
|
||||
echo "==> Build successful"
|
||||
ls -lh build/${{ env.PROJECT_NAME }}
|
||||
file build/${{ env.PROJECT_NAME }}
|
||||
|
||||
- name: Run size analysis
|
||||
run: |
|
||||
size build/${{ env.PROJECT_NAME }}
|
||||
|
||||
- name: Upload build artifact
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: ${{ env.PROJECT_NAME }}-${{ matrix.os }}-${{ matrix.build_type }}
|
||||
path: build/${{ env.PROJECT_NAME }}
|
||||
retention-days: 7
|
||||
|
||||
build-warnings:
|
||||
name: Build with strict warnings
|
||||
runs-on: ubuntu-latest
|
||||
needs: lint
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y \
|
||||
build-essential \
|
||||
meson \
|
||||
ninja-build \
|
||||
pkg-config \
|
||||
libgtk-4-dev \
|
||||
libvte-2.91-gtk4-dev \
|
||||
libfreetype-dev \
|
||||
libpango1.0-dev \
|
||||
libcairo2-dev
|
||||
|
||||
- name: Configure with strict warnings
|
||||
run: |
|
||||
meson setup build \
|
||||
--buildtype=debug \
|
||||
--werror \
|
||||
-Dwarning_level=3
|
||||
|
||||
- name: Build with strict warnings
|
||||
run: |
|
||||
meson compile -C build 2>&1 | tee build-warnings.log
|
||||
continue-on-error: true
|
||||
|
||||
- name: Upload warnings log
|
||||
uses: actions/upload-artifact@v4
|
||||
if: always()
|
||||
with:
|
||||
name: build-warnings-log
|
||||
path: build-warnings.log
|
||||
retention-days: 30
|
||||
|
||||
memory-check:
|
||||
name: Memory Analysis
|
||||
runs-on: ubuntu-latest
|
||||
needs: build-matrix
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y \
|
||||
build-essential \
|
||||
meson \
|
||||
ninja-build \
|
||||
pkg-config \
|
||||
libgtk-4-dev \
|
||||
libvte-2.91-gtk4-dev \
|
||||
libfreetype-dev \
|
||||
libpango1.0-dev \
|
||||
libcairo2-dev \
|
||||
valgrind \
|
||||
xvfb
|
||||
|
||||
- name: Build debug version
|
||||
run: |
|
||||
meson setup build --buildtype=debug
|
||||
meson compile -C build
|
||||
|
||||
- name: Run Valgrind analysis
|
||||
run: |
|
||||
timeout 30 xvfb-run -a valgrind \
|
||||
--leak-check=full \
|
||||
--show-leak-kinds=definite,indirect,possible \
|
||||
--track-origins=yes \
|
||||
--error-exitcode=0 \
|
||||
--xml=yes \
|
||||
--xml-file=valgrind-report.xml \
|
||||
build/${{ env.PROJECT_NAME }} &
|
||||
sleep 10
|
||||
pkill -f "${{ env.PROJECT_NAME }}" || true
|
||||
continue-on-error: true
|
||||
|
||||
- name: Upload Valgrind report
|
||||
uses: actions/upload-artifact@v4
|
||||
if: always()
|
||||
with:
|
||||
name: valgrind-report
|
||||
path: valgrind-report.xml
|
||||
retention-days: 30
|
||||
|
||||
sanitizer-check:
|
||||
name: Sanitizer Analysis
|
||||
runs-on: ubuntu-latest
|
||||
needs: lint
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
sanitizer: [address, undefined]
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y \
|
||||
build-essential \
|
||||
meson \
|
||||
ninja-build \
|
||||
pkg-config \
|
||||
libgtk-4-dev \
|
||||
libvte-2.91-gtk4-dev \
|
||||
libfreetype-dev \
|
||||
libpango1.0-dev \
|
||||
libcairo2-dev \
|
||||
xvfb
|
||||
|
||||
- name: Build with ${{ matrix.sanitizer }} sanitizer
|
||||
env:
|
||||
CFLAGS: "-fsanitize=${{ matrix.sanitizer }} -fno-omit-frame-pointer -g"
|
||||
LDFLAGS: "-fsanitize=${{ matrix.sanitizer }}"
|
||||
run: |
|
||||
meson setup build --buildtype=debug
|
||||
meson compile -C build
|
||||
|
||||
- name: Run sanitizer check
|
||||
env:
|
||||
ASAN_OPTIONS: "detect_leaks=1:abort_on_error=0:log_path=asan.log"
|
||||
UBSAN_OPTIONS: "print_stacktrace=1:halt_on_error=0:log_path=ubsan.log"
|
||||
run: |
|
||||
timeout 15 xvfb-run -a build/${{ env.PROJECT_NAME }} &
|
||||
sleep 10
|
||||
pkill -f "${{ env.PROJECT_NAME }}" || true
|
||||
continue-on-error: true
|
||||
|
||||
- name: Upload sanitizer logs
|
||||
uses: actions/upload-artifact@v4
|
||||
if: always()
|
||||
with:
|
||||
name: ${{ matrix.sanitizer }}-sanitizer-logs
|
||||
path: |
|
||||
asan.log*
|
||||
ubsan.log*
|
||||
retention-days: 30
|
||||
|
||||
package:
|
||||
name: Create packages
|
||||
runs-on: ubuntu-latest
|
||||
needs: build-matrix
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y \
|
||||
build-essential \
|
||||
meson \
|
||||
ninja-build \
|
||||
pkg-config \
|
||||
libgtk-4-dev \
|
||||
libvte-2.91-gtk4-dev \
|
||||
libfreetype-dev \
|
||||
libpango1.0-dev \
|
||||
libcairo2-dev \
|
||||
dpkg-dev
|
||||
|
||||
- name: Build release
|
||||
run: |
|
||||
meson setup build --buildtype=release --prefix=/usr
|
||||
meson compile -C build
|
||||
strip build/${{ env.PROJECT_NAME }}
|
||||
|
||||
- name: Create source tarball
|
||||
run: |
|
||||
make dist
|
||||
|
||||
- name: Create Debian package
|
||||
run: |
|
||||
VERSION=$(grep "version:" meson.build | head -1 | grep -oP "'[0-9.]+'")
|
||||
VERSION=${VERSION//\'/}
|
||||
|
||||
mkdir -p pkg/DEBIAN
|
||||
mkdir -p pkg/usr/bin
|
||||
mkdir -p pkg/usr/share/applications
|
||||
mkdir -p pkg/usr/share/icons/hicolor/scalable/apps
|
||||
mkdir -p pkg/usr/share/${{ env.PROJECT_NAME }}
|
||||
|
||||
cp build/${{ env.PROJECT_NAME }} pkg/usr/bin/
|
||||
cp data/rt.desktop pkg/usr/share/applications/
|
||||
cp data/rt.svg pkg/usr/share/icons/hicolor/scalable/apps/
|
||||
cp config/rt.conf.example pkg/usr/share/${{ env.PROJECT_NAME }}/
|
||||
|
||||
cat > pkg/DEBIAN/control << EOF
|
||||
Package: ${{ env.PROJECT_NAME }}
|
||||
Version: ${VERSION}
|
||||
Section: x11
|
||||
Priority: optional
|
||||
Architecture: amd64
|
||||
Depends: libgtk-4-1 (>= 4.10), libvte-2.91-gtk4-0 (>= 0.76)
|
||||
Maintainer: RT Terminal Developers <rt-terminal@example.com>
|
||||
Homepage: https://example.com/rt-terminal
|
||||
Description: Fast enterprise-grade terminal emulator
|
||||
RT (Rapid Terminal) is an enterprise-grade terminal emulator
|
||||
featuring exceptional text rendering with high-DPI support,
|
||||
complete ANSI escape sequence handling, and robust PTY
|
||||
communication. Built with GTK4 and VTE.
|
||||
EOF
|
||||
|
||||
dpkg-deb --build pkg ${{ env.PROJECT_NAME }}_${VERSION}_amd64.deb
|
||||
rm -rf pkg
|
||||
|
||||
- name: Upload packages
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: packages
|
||||
path: |
|
||||
dist/*.tar.gz
|
||||
*.deb
|
||||
retention-days: 30
|
||||
|
||||
integration-test:
|
||||
name: Integration Tests
|
||||
runs-on: ubuntu-latest
|
||||
needs: build-matrix
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y \
|
||||
build-essential \
|
||||
meson \
|
||||
ninja-build \
|
||||
pkg-config \
|
||||
libgtk-4-dev \
|
||||
libvte-2.91-gtk4-dev \
|
||||
libfreetype-dev \
|
||||
libpango1.0-dev \
|
||||
libcairo2-dev \
|
||||
xvfb \
|
||||
xdotool
|
||||
|
||||
- name: Build project
|
||||
run: |
|
||||
meson setup build --buildtype=release
|
||||
meson compile -C build
|
||||
|
||||
- name: Test application startup
|
||||
run: |
|
||||
echo "==> Testing application startup..."
|
||||
timeout 15 xvfb-run -a build/${{ env.PROJECT_NAME }} &
|
||||
APP_PID=$!
|
||||
sleep 5
|
||||
|
||||
if ps -p $APP_PID > /dev/null 2>&1; then
|
||||
echo "==> Application started successfully (PID: $APP_PID)"
|
||||
kill $APP_PID 2>/dev/null || true
|
||||
echo "==> Startup test PASSED"
|
||||
else
|
||||
echo "==> Application failed to start"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
- name: Test configuration loading
|
||||
run: |
|
||||
echo "==> Testing configuration system..."
|
||||
mkdir -p ~/.config/rt
|
||||
cat > ~/.config/rt/rt.conf << EOF
|
||||
[font]
|
||||
family=Monospace
|
||||
size=12
|
||||
|
||||
[theme]
|
||||
name=Nord
|
||||
|
||||
[terminal]
|
||||
scrollback_lines=5000
|
||||
EOF
|
||||
|
||||
timeout 10 xvfb-run -a build/${{ env.PROJECT_NAME }} &
|
||||
sleep 5
|
||||
pkill -f "${{ env.PROJECT_NAME }}" || true
|
||||
echo "==> Configuration test PASSED"
|
||||
|
||||
- name: Test shell spawning
|
||||
run: |
|
||||
echo "==> Testing shell spawn..."
|
||||
timeout 10 xvfb-run -a build/${{ env.PROJECT_NAME }} &
|
||||
sleep 3
|
||||
|
||||
if pgrep -f "bash.*-l" > /dev/null || pgrep -f "sh.*-l" > /dev/null; then
|
||||
echo "==> Shell spawned successfully"
|
||||
fi
|
||||
|
||||
pkill -f "${{ env.PROJECT_NAME }}" || true
|
||||
echo "==> Shell spawn test PASSED"
|
||||
|
||||
documentation:
|
||||
name: Documentation Check
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Check documentation completeness
|
||||
run: |
|
||||
echo "==> Checking documentation..."
|
||||
|
||||
MISSING=0
|
||||
|
||||
for file in README.md LICENSE; do
|
||||
if [ ! -f "$file" ]; then
|
||||
echo "MISSING: $file"
|
||||
MISSING=1
|
||||
else
|
||||
echo "OK: $file"
|
||||
fi
|
||||
done
|
||||
|
||||
for file in data/rt.desktop data/rt.svg config/rt.conf.example; do
|
||||
if [ ! -f "$file" ]; then
|
||||
echo "MISSING: $file"
|
||||
MISSING=1
|
||||
else
|
||||
echo "OK: $file"
|
||||
fi
|
||||
done
|
||||
|
||||
if [ $MISSING -eq 1 ]; then
|
||||
echo "==> Documentation check FAILED"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "==> Documentation check PASSED"
|
||||
|
||||
- name: Validate desktop file
|
||||
run: |
|
||||
if command -v desktop-file-validate >/dev/null 2>&1; then
|
||||
desktop-file-validate data/rt.desktop
|
||||
else
|
||||
echo "desktop-file-validate not available, skipping"
|
||||
fi
|
||||
|
||||
ci-summary:
|
||||
name: CI Summary
|
||||
runs-on: ubuntu-latest
|
||||
needs:
|
||||
- lint
|
||||
- build-matrix
|
||||
- build-warnings
|
||||
- memory-check
|
||||
- sanitizer-check
|
||||
- package
|
||||
- integration-test
|
||||
- documentation
|
||||
if: always()
|
||||
steps:
|
||||
- name: Check job results
|
||||
run: |
|
||||
echo "## CI Pipeline Summary" >> $GITHUB_STEP_SUMMARY
|
||||
echo "" >> $GITHUB_STEP_SUMMARY
|
||||
echo "| Job | Status |" >> $GITHUB_STEP_SUMMARY
|
||||
echo "|-----|--------|" >> $GITHUB_STEP_SUMMARY
|
||||
echo "| Lint | ${{ needs.lint.result }} |" >> $GITHUB_STEP_SUMMARY
|
||||
echo "| Build Matrix | ${{ needs.build-matrix.result }} |" >> $GITHUB_STEP_SUMMARY
|
||||
echo "| Build Warnings | ${{ needs.build-warnings.result }} |" >> $GITHUB_STEP_SUMMARY
|
||||
echo "| Memory Check | ${{ needs.memory-check.result }} |" >> $GITHUB_STEP_SUMMARY
|
||||
echo "| Sanitizer Check | ${{ needs.sanitizer-check.result }} |" >> $GITHUB_STEP_SUMMARY
|
||||
echo "| Package | ${{ needs.package.result }} |" >> $GITHUB_STEP_SUMMARY
|
||||
echo "| Integration Test | ${{ needs.integration-test.result }} |" >> $GITHUB_STEP_SUMMARY
|
||||
echo "| Documentation | ${{ needs.documentation.result }} |" >> $GITHUB_STEP_SUMMARY
|
||||
|
||||
- name: Determine overall status
|
||||
run: |
|
||||
if [ "${{ needs.lint.result }}" != "success" ] || \
|
||||
[ "${{ needs.build-matrix.result }}" != "success" ] || \
|
||||
[ "${{ needs.integration-test.result }}" != "success" ]; then
|
||||
echo "==> CI Pipeline FAILED"
|
||||
exit 1
|
||||
fi
|
||||
echo "==> CI Pipeline PASSED"
|
||||
Reference in New Issue
Block a user