Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions .github/pull_request_template.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
## Pull request (PR) description:
> Provide a brief description of the PR here.
>
> It does not need to list what each individual commit does, but rather provide a high-level overview of the PR.

## Issues resolved:
> Any associated issues should be provided here using the format: 'Resolves #<issue>' (e.g. Resolves #1). If there are none, use 'n/a' instead.
249 changes: 249 additions & 0 deletions .github/workflows/pr-ci-report.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,249 @@
name: Pull Request CI Report

on:
pull_request:

permissions:
contents: read
pull-requests: write

jobs:
python-tests:
name: Python ${{ matrix.python-version }} (${{ matrix.os }})
runs-on: ${{ matrix.os }}
if: github.event.pull_request.head.repo.full_name == github.repository
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest, macos-latest]
python-version: ["3.14", "3.15"]
steps:
- uses: actions/checkout@v7

- name: OS version (Linux)
if: runner.os == 'Linux'
shell: bash
run: |
. /etc/os-release
echo "OS_NAME=$NAME" >> "$GITHUB_ENV"
echo "OS_VER=$VERSION_ID" >> "$GITHUB_ENV"

- name: OS version (macOS)
if: runner.os == 'macOS'
shell: bash
run: |
echo "OS_NAME=macOS" >> "$GITHUB_ENV"
echo "OS_VER=$(sw_vers -productVersion)" >> "$GITHUB_ENV"

- name: Install Linux Qt runtime dependencies
if: runner.os == 'Linux'
shell: bash
run: |
sudo apt-get update
sudo apt-get install -y \
libegl1 \
libgl1 \
libdbus-1-3 \
libxkbcommon-x11-0 \
libxcb-cursor0 \
libxcb-icccm4 \
libxcb-image0 \
libxcb-keysyms1 \
libxcb-randr0 \
libxcb-render-util0 \
libxcb-shape0 \
libxcb-xinerama0 \
libxcb-xfixes0 \
xvfb

- name: Install uv
uses: astral-sh/setup-uv@ae62891fec2bb8e7d6c99fc78c9fec3a63790f8d
with:
python-version: ${{ matrix.python-version }}

- name: Sync dependencies
run: uv sync --all-extras

- name: Run pytest
id: pytest
continue-on-error: true
run: uv run pytest

- name: Build package
id: build
continue-on-error: true
run: uv build

- name: Add venv bin to PATH
shell: bash
run: echo "$PWD/.venv/bin" >> "$GITHUB_PATH"

- name: Check CLI entry point
id: cli
continue-on-error: true
run: comms --help

- name: Write result file
if: always()
shell: bash
run: |
mkdir -p result
cat > result/result.json <<EOF
{
"os_name": "${{ env.OS_NAME }}",
"os_ver": "${{ env.OS_VER }}",
"python_version": "${{ matrix.python-version }}",
"tests": "${{ steps.pytest.outcome == 'success' && 'pass' || 'fail' }}",
"build": "${{ steps.build.outcome == 'success' && 'pass' || 'fail' }}",
"cli": "${{ steps.cli.outcome == 'success' && 'pass' || 'fail' }}"
}
EOF

- name: Upload result artifact
if: always()
uses: actions/upload-artifact@v7
with:
name: python-result-${{ matrix.os }}-${{ matrix.python-version }}
path: result/result.json

- name: Fail if any check failed
if: always() && (steps.pytest.outcome == 'failure' || steps.build.outcome == 'failure' || steps.cli.outcome == 'failure')
run: exit 1

r-tests:
name: R ${{ matrix.r-version }} (${{ matrix.os }})
runs-on: ${{ matrix.os }}
if: github.event.pull_request.head.repo.full_name == github.repository
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest, macos-latest]
r-version: ["4.4.3", "4.5.3", "4.6.1"]
steps:
- uses: actions/checkout@v7

- name: OS version (Linux)
if: runner.os == 'Linux'
shell: bash
run: |
. /etc/os-release
echo "OS_NAME=$NAME" >> "$GITHUB_ENV"
echo "OS_VER=$VERSION_ID" >> "$GITHUB_ENV"
echo "USE_BUNDLED_LIBUV=1" >> "$GITHUB_ENV"

- name: OS version (macOS)
if: runner.os == 'macOS'
shell: bash
run: |
echo "OS_NAME=macOS" >> "$GITHUB_ENV"
echo "OS_VER=$(sw_vers -productVersion)" >> "$GITHUB_ENV"

- name: Install Linux runtime dependencies
if: runner.os == 'Linux'
shell: bash
run: |
sudo apt-get update
sudo apt-get install -y \
libcurl4-openssl-dev \
libfontconfig1-dev \
libfreetype6-dev \
libfribidi-dev \
libharfbuzz-dev \
libjpeg-dev \
libpng-dev \
libtiff5-dev \
libwebp-dev

- name: Set up R
uses: r-lib/actions/setup-r@v2
with:
r-version: ${{ matrix.r-version }}
use-public-rspm: true

- name: Install R dependencies
run: |
Rscript -e 'install.packages("testthat", repos = "https://cloud.r-project.org")'
Rscript src/comms/r/deps/install_deps.R

- name: Run R tests
id: rtests
continue-on-error: true
run: Rscript -e 'testthat::test_dir("tests/r")'

- name: Write result file
if: always()
shell: bash
run: |
mkdir -p result
cat > result/result.json <<EOF
{
"os_name": "${{ env.OS_NAME }}",
"os_ver": "${{ env.OS_VER }}",
"r_version": "${{ matrix.r-version }}",
"tests": "${{ steps.rtests.outcome == 'success' && 'pass' || 'fail' }}"
}
EOF

- name: Upload result artifact
if: always()
uses: actions/upload-artifact@v7
with:
name: r-result-${{ matrix.os }}-${{ matrix.r-version }}
path: result/result.json

- name: Fail if R tests failed
if: always() && steps.rtests.outcome == 'failure'
run: exit 1

all-checks-passed:
name: All checks passed
needs: [python-tests, r-tests]
if: always() && github.event.pull_request.head.repo.full_name == github.repository
runs-on: ubuntu-latest
steps:
- name: Check job results
run: |
if [ "${{ needs.python-tests.result }}" != "success" ] || \
[ "${{ needs.r-tests.result }}" != "success" ]; then
echo "One or more required checks failed."
exit 1
fi
echo "All required checks passed."

summary:
name: Post pull request CI report
needs: [python-tests, r-tests]
if: always() && github.event.pull_request.head.repo.full_name == github.repository
runs-on: ubuntu-latest
steps:
- name: Checkout branch for workflow script
uses: actions/checkout@v7

- name: Download Python results
uses: actions/download-artifact@v7
continue-on-error: true
with:
pattern: python-result-*
path: results/python

- name: Download R results
uses: actions/download-artifact@v7
continue-on-error: true
with:
pattern: r-result-*
path: results/r

- name: List all downloaded files
shell: bash
run: ls -a

- name: Build summary
id: build
shell: bash
run: python3 .github/workflows/pr_ci_report.py

- name: Comment on pull request
uses: marocchino/sticky-pull-request-comment@v3
with:
header: pull-request-ci-report
path: pr_ci_report.md
66 changes: 66 additions & 0 deletions .github/workflows/pr-version-check.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
name: Main Branch Pull Request Version Check

on:
pull_request:
branches: [main]

permissions:
contents: read

jobs:
version-check:
name: Check version bump
runs-on: ubuntu-latest
steps:
- name: Checkout PR branch
uses: actions/checkout@v7

- name: Read PR version
id: pr_version
run: |
VERSION=$(grep -m1 '^version *= *' pyproject.toml | sed -E 's/version *= *"([^"]+)"/\1/')
if [ -z "$VERSION" ]; then
echo "Could not read version from pyproject.toml" >&2
exit 1
fi
echo "version=$VERSION" >> "$GITHUB_OUTPUT"

- name: Read main version
id: main_version
run: |
git fetch origin main --depth=1
VERSION=$(git show origin/main:pyproject.toml | grep -m1 '^version *= *' | sed -E 's/version *= *"([^"]+)"/\1/')
if [ -z "$VERSION" ]; then
echo "Could not read version from main's pyproject.toml" >&2
exit 1
fi
echo "version=$VERSION" >> "$GITHUB_OUTPUT"

- name: Install uv
uses: astral-sh/setup-uv@ae62891fec2bb8e7d6c99fc78c9fec3a63790f8d

- name: Compare versions
run: |
PR_VERSION="${{ steps.pr_version.outputs.version }}"
MAIN_VERSION="${{ steps.main_version.outputs.version }}"
echo "PR version: $PR_VERSION"
echo "main version: $MAIN_VERSION"
uv run --with packaging python3 - "$PR_VERSION" "$MAIN_VERSION" <<'EOF'
import sys
from packaging.version import Version, InvalidVersion

pr_raw, main_raw = sys.argv[1], sys.argv[2]

try:
pr = Version(pr_raw)
main = Version(main_raw)
except InvalidVersion as e:
print(f"Could not parse version as PEP 440: {e}", file=sys.stderr)
sys.exit(1)

if pr <= main:
print(f'Version in pyproject.toml ({pr_raw}) is not greater than main ({main_raw}). Versions must strictly increase.'', file=sys.stderr)
sys.exit(1)

print(f'OK: {pr_raw} > {main_raw}'')
EOF
Loading