Migrate CI/deploy pipeline from GitHub Actions to Gitea Actions
docker-build-push / build-push-deploy (push) Successful in 33s

Build/test/push now runs as .gitea/workflows/docker-build-push.yml,
pushing to gitea.blairhaus.net/pmb/finger and auto-deploying to mammut
and bsd on every push to main, since GitHub is no longer in use.
Removes the now-dead .github workflows, .codecov.yml, and their README
badges.
This commit is contained in:
waffle2k
2026-07-23 21:56:11 -07:00
parent dcbcff98a6
commit c33066d33e
7 changed files with 59 additions and 470 deletions
-26
View File
@@ -1,26 +0,0 @@
coverage:
status:
project:
default:
target: 80%
threshold: 5%
patch:
default:
target: 80%
threshold: 5%
comment:
layout: "reach,diff,flags,tree"
behavior: default
require_changes: false
ignore:
- "test_*.cpp"
- "builddir/**/*"
- "**/*.hpp" # Header files typically don't need coverage
flags:
unittests:
paths:
- handler.cpp
- main.cpp
+3
View File
@@ -2,6 +2,9 @@
builddir/
testbuild/
# Rust port (separate build, own Dockerfile)
rust/
# Git
.git/
.gitignore
+56
View File
@@ -0,0 +1,56 @@
name: docker-build-push
on:
push:
branches: [main]
workflow_dispatch:
jobs:
build-push-deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
# act_runner bind-mounts the admin host's real Docker socket into every
# job container (Docker-outside-of-Docker, not a nested daemon), so
# `docker` here talks straight to the host's daemon — no separate
# dockerd to start. The Dockerfile's builder stage runs `meson test`,
# so a failing test fails this build before anything gets pushed.
- name: Build, test, and push image
env:
REGISTRY_TOKEN: ${{ secrets.REGISTRY_TOKEN }}
run: |
SHA="${{ github.sha }}"
IMAGE="gitea.blairhaus.net/pmb/finger"
docker build -t "$IMAGE:$SHA" -t "$IMAGE:latest" .
printf '%s' "$REGISTRY_TOKEN" | docker login gitea.blairhaus.net -u pmb --password-stdin
docker push "$IMAGE:$SHA"
docker push "$IMAGE:latest"
docker logout gitea.blairhaus.net
echo "pushed $IMAGE:$SHA and $IMAGE:latest"
# Deploy: hop into the admin host itself (job containers can only reach
# host.docker.internal directly), then from there reuse admin's own
# already-configured `ssh mammut`/`ssh bsd` aliases to reach the two
# real deploy targets.
- name: Deploy to mammut and bsd
env:
ADMIN_HOST_SSH_KEY: ${{ secrets.ADMIN_HOST_SSH_KEY }}
run: |
mkdir -p ~/.ssh
printf '%s\n' "$ADMIN_HOST_SSH_KEY" > ~/.ssh/id_ed25519
chmod 600 ~/.ssh/id_ed25519
ssh-keyscan -H host.docker.internal >> ~/.ssh/known_hosts 2>/dev/null
scp -i ~/.ssh/id_ed25519 update-fingerd.sh [email protected]:/tmp/update-fingerd.sh
ssh -i ~/.ssh/id_ed25519 [email protected] bash -s <<'EOF'
set -euo pipefail
ssh mammut "cd ~/finger && docker compose pull && docker compose up -d" < /dev/null
ssh bsd 'sh -s' < /tmp/update-fingerd.sh
rm -f /tmp/update-fingerd.sh
EOF
echo "deployed to mammut + bsd"
-179
View File
@@ -1,179 +0,0 @@
# GitHub Actions CI/CD Setup
This repository includes a comprehensive GitHub Actions workflow for C++20 compilation, testing, and code coverage reporting.
## Features
### 🔧 Multi-Platform Build & Test
- **Ubuntu Latest**: Primary development target with GCC
- **macOS Latest**: Cross-platform compatibility with Clang
- **Windows Latest**: Broader compatibility with GCC via vcpkg
### 🧪 Comprehensive Testing
- Runs all Google Test unit tests
- Validates security features (directory traversal protection)
- Fails build on any test failures
- Uploads test logs as artifacts
### 📊 Code Coverage Reporting
- **Coverage Tool**: gcov + lcov for detailed coverage analysis
- **Integration**: Automatic upload to Codecov.io
- **Reports**: HTML coverage reports as downloadable artifacts
- **Thresholds**: Configurable coverage targets (default: 80%)
- **PR Comments**: Automatic coverage change reporting
## Workflow Structure
```
CI Workflow
├── Build & Test Matrix (Ubuntu, macOS, Windows)
│ ├── Install Dependencies (Boost, Google Test)
│ ├── Meson Setup & Configure
│ ├── Compile with C++20
│ ├── Run Unit Tests
│ └── Upload Test Artifacts
└── Coverage Analysis (Ubuntu only)
├── Build with Coverage Flags
├── Run Tests with Coverage Collection
├── Generate lcov Reports
├── Upload to Codecov
└── Generate HTML Reports
```
## Setup Instructions
### 1. Repository Setup
1. Push this repository to GitHub
2. Update the badge URLs in `README.md`:
```markdown
[![CI](https://github.com/YOUR_USERNAME/YOUR_REPO_NAME/workflows/CI/badge.svg)](https://github.com/YOUR_USERNAME/YOUR_REPO_NAME/actions)
[![codecov](https://codecov.io/gh/YOUR_USERNAME/YOUR_REPO_NAME/branch/main/graph/badge.svg)](https://codecov.io/gh/YOUR_USERNAME/YOUR_REPO_NAME)
```
### 2. Codecov Integration
1. Visit [codecov.io](https://codecov.io) and sign in with GitHub
2. Add your repository to Codecov
3. No additional setup required - the workflow handles token-free uploads
### 3. Branch Protection (Optional)
Configure branch protection rules in GitHub:
- Require status checks to pass before merging
- Require branches to be up to date before merging
- Include the "Build and Test" and "Code Coverage" checks
## Configuration Files
### `.github/workflows/ci.yml`
Main CI/CD workflow with:
- Multi-platform build matrix
- Dependency management for each OS
- Test execution and artifact collection
- Coverage analysis and reporting
### `.codecov.yml`
Codecov configuration with:
- Coverage targets (80% project, 80% patch)
- File exclusions (test files, build directories)
- PR comment formatting
- Coverage flags for different components
### `.gitignore` Updates
Added coverage-related file exclusions:
- `*.gcda`, `*.gcno`, `*.gcov` - Coverage data files
- `coverage/` - Coverage report directories
- `coverage*.info` - lcov report files
## Workflow Triggers
The CI workflow runs on:
- **Push** to `main` and `develop` branches
- **Pull Requests** targeting `main` and `develop` branches
## Artifacts Generated
### Test Results
- Test logs from all platforms
- Available for 90 days after workflow completion
### Coverage Reports
- HTML coverage reports (viewable in browser)
- lcov data files for further analysis
- Codecov integration for web-based viewing
## Coverage Analysis
The coverage analysis focuses on:
- `handler.cpp` - Core business logic
- Security validation functions
- File I/O operations
- Excludes test files and system headers
### Coverage Thresholds
- **Project Coverage**: 80% minimum
- **Patch Coverage**: 80% minimum for new code
- **Threshold**: 5% tolerance for coverage changes
## Troubleshooting
### Common Issues
1. **Dependency Installation Failures**
- Check if package names are correct for the target OS
- Verify vcpkg installation on Windows
2. **Coverage Upload Failures**
- Coverage uploads are set to non-blocking (`fail_ci_if_error: false`)
- Check Codecov repository configuration
3. **Test Failures**
- Review test logs in the workflow artifacts
- Ensure all tests pass locally before pushing
### Local Testing
Test the workflow components locally:
```bash
# Standard build and test
meson setup builddir
meson compile -C builddir
meson test -C builddir --verbose
# Coverage build and test
meson setup builddir-coverage -Db_coverage=true
meson compile -C builddir-coverage
meson test -C builddir-coverage
```
## Customization
### Adding New Platforms
Extend the build matrix in `.github/workflows/ci.yml`:
```yaml
matrix:
os: [ubuntu-latest, macos-latest, windows-latest, ubuntu-20.04]
```
### Changing Coverage Targets
Modify `.codecov.yml`:
```yaml
coverage:
status:
project:
default:
target: 90% # Increase to 90%
```
### Adding Static Analysis
Add steps to the workflow for tools like:
- cppcheck
- clang-tidy
- AddressSanitizer/UBSan (already partially enabled)
## Security Considerations
The workflow includes security best practices:
- Pinned action versions (`@v4`, `@v3`)
- No secrets required for basic functionality
- Minimal permissions for workflow execution
- Static linking to reduce runtime dependencies
-138
View File
@@ -1,138 +0,0 @@
name: CI
on:
push:
branches: [ main, develop ]
pull_request:
branches: [ main, develop ]
jobs:
build-and-test:
name: Build and Test
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest]
include:
- os: ubuntu-latest
cc: gcc
cxx: g++
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Setup Python
uses: actions/setup-python@v4
with:
python-version: '3.x'
- name: Install Meson and Ninja
run: |
python -m pip install --upgrade pip
pip install meson ninja
- name: Install dependencies (Ubuntu)
if: matrix.os == 'ubuntu-latest'
run: |
sudo apt-get update
sudo apt-get install -y libboost-system-dev libgtest-dev libgmock-dev build-essential
- name: Setup build directory
run: |
meson setup builddir
env:
CC: ${{ matrix.cc }}
CXX: ${{ matrix.cxx }}
- name: Compile
run: |
meson compile -C builddir
- name: Run tests
run: |
meson test -C builddir --verbose
- name: Upload test results
uses: actions/upload-artifact@v4
if: always()
with:
name: test-results-${{ matrix.os }}
path: builddir/meson-logs/
coverage:
name: Code Coverage
runs-on: ubuntu-latest
needs: build-and-test
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Setup Python
uses: actions/setup-python@v4
with:
python-version: '3.x'
- name: Install Meson and Ninja
run: |
python -m pip install --upgrade pip
pip install meson ninja
- name: Install dependencies and coverage tools
run: |
sudo apt-get update
sudo apt-get install -y libboost-system-dev libgtest-dev libgmock-dev build-essential lcov
- name: Setup build directory with coverage
run: |
meson setup builddir -Db_coverage=true
env:
CC: gcc
CXX: g++
- name: Compile with coverage
run: |
meson compile -C builddir
- name: Run tests with coverage
run: |
meson test -C builddir --verbose
- name: Generate coverage report
run: |
# Create coverage directory
mkdir -p coverage
# Capture coverage data
lcov --capture --directory builddir --output-file coverage/coverage.info --ignore-errors mismatch,mismatch,unused
# Remove system headers and test files from coverage
lcov --remove coverage/coverage.info '/usr/*' '*/test_*' '*/gtest/*' --output-file coverage/coverage_filtered.info --ignore-errors mismatch,mismatch,unused
# Generate HTML report
genhtml coverage/coverage_filtered.info --output-directory coverage/html
# Display coverage summary
lcov --summary coverage/coverage_filtered.info --ignore-errors mismatch,mismatch,unused
- name: Upload coverage reports to Codecov
uses: codecov/codecov-action@v3
with:
file: coverage/coverage_filtered.info
flags: unittests
name: codecov-umbrella
fail_ci_if_error: false
- name: Upload coverage HTML report
uses: actions/upload-artifact@v4
with:
name: coverage-report
path: coverage/html/
- name: Coverage Summary
run: |
echo "## Coverage Report" >> $GITHUB_STEP_SUMMARY
echo "Coverage data has been uploaded to Codecov and HTML report is available as an artifact." >> $GITHUB_STEP_SUMMARY
lcov --summary coverage/coverage_filtered.info >> $GITHUB_STEP_SUMMARY
-124
View File
@@ -1,124 +0,0 @@
name: Build and Publish Docker Image
on:
push:
branches: [ "main" ]
tags: [ 'v*.*.*' ]
pull_request:
branches: [ "main" ]
env:
REGISTRY: ghcr.io
IMAGE_NAME: ${{ github.repository }}
jobs:
build-and-test:
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 \
build-essential \
meson \
ninja-build \
pkg-config \
libboost-all-dev \
libgtest-dev \
libgmock-dev
- name: Setup build directory
run: meson setup builddir --buildtype=release
- name: Build project
run: meson compile -C builddir
- name: Run tests
run: meson test -C builddir
- name: Upload test results
uses: actions/upload-artifact@v4
if: always()
with:
name: test-results
path: builddir/meson-logs/testlog.txt
build-and-push-image:
runs-on: ubuntu-latest
needs: build-and-test
permissions:
contents: read
packages: write
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Log in to Container Registry
if: github.event_name != 'pull_request'
uses: docker/login-action@v3
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Extract metadata (tags, labels) for Docker
id: meta
uses: docker/metadata-action@v5
with:
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
tags: |
type=ref,event=branch
type=ref,event=pr
type=semver,pattern={{version}}
type=semver,pattern={{major}}.{{minor}}
type=semver,pattern={{major}}
type=sha,prefix={{branch}}-
type=raw,value=latest,enable={{is_default_branch}}
- name: Build and push Docker image
uses: docker/build-push-action@v5
with:
context: .
platforms: linux/amd64,linux/arm64
push: ${{ github.event_name != 'pull_request' }}
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
cache-from: type=gha
cache-to: type=gha,mode=max
- name: Generate artifact attestation
if: github.event_name != 'pull_request'
uses: actions/attest-build-provenance@v1
with:
subject-name: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
subject-digest: ${{ steps.build.outputs.digest }}
push-to-registry: true
security-scan:
runs-on: ubuntu-latest
needs: build-and-push-image
if: github.event_name != 'pull_request'
permissions:
contents: read
security-events: write
steps:
- name: Run Trivy vulnerability scanner
uses: aquasecurity/trivy-action@master
with:
image-ref: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:latest
format: 'sarif'
output: 'trivy-results.sarif'
- name: Upload Trivy scan results to GitHub Security tab
uses: github/codeql-action/upload-sarif@v3
with:
sarif_file: 'trivy-results.sarif'
-3
View File
@@ -1,8 +1,5 @@
# finger
[![CI](https://github.com/waffle2k/finger/workflows/CI/badge.svg)](https://github.com/waffle2k/finger/actions)
[![codecov](https://codecov.io/gh/waffle2k/finger/branch/main/graph/badge.svg)](https://codecov.io/gh/waffle2k/finger)
A silly finger service written in c++20
# Compiling: