This document covers the testing infrastructure and continuous integration (CI) pipelines used in the g4f project. This includes unit testing, automated code review, multi-platform build workflows, and release automation.
For information about deployment and Docker builds, see Deployment. For development setup and local testing, see Development Setup.
The g4f project uses GitHub Actions for continuous integration with multiple workflows handling different aspects of testing, code review, building, and distribution. The testing infrastructure includes:
Sources: .github/workflows/unittest.yml1-46 .github/workflows/copilot.yml1-58 .github/workflows/build-packages.yml1-490
Workflow Dependencies: The copilot.yml workflow depends on the completion of unittest.yml via the workflow_run trigger. This ensures that code review only runs after tests have completed. The PR number is passed between workflows using GitHub Actions artifacts.
Sources: .github/workflows/unittest.yml3-11 .github/workflows/copilot.yml4-7 .github/workflows/build-packages.yml3-12 .github/workflows/publish-to-pypi.yml3
Conditional Test Execution: Tests in TestBackendApi use skipTest() to gracefully handle missing dependencies. The test suite checks for the availability of GUI requirements (has_requirements) and search functionality (has_search) before executing respective tests.
Sources: etc/unittest/main.py1-17 etc/unittest/backend.py1-57
| Test Class | File | Methods | Purpose |
|---|---|---|---|
TestGetLastProvider | etc/unittest/main.py | test_get_latest_version | Validates version checking functionality, ensures current_version and latest_version are properly set |
TestBackendApi | etc/unittest/backend.py | test_version, test_get_models, test_get_providers, test_search | Tests Backend API endpoints and search integration |
Backend API Tests:
test_version() - Verifies the API returns version information with keys "version" and "latest_version" etc/unittest/backend.py31-34test_get_models() - Ensures model list endpoint returns a non-empty list etc/unittest/backend.py36-39test_get_providers() - Validates provider list endpoint returns a non-empty list etc/unittest/backend.py41-44test_search() - Tests web search integration, handles DDGSException and missing requirements gracefully etc/unittest/backend.py46-56Sources: etc/unittest/main.py8-17 etc/unittest/backend.py23-57
The unittest.yml workflow executes tests on two Python versions to ensure compatibility:
Python Version Testing Strategy:
requirements-min.txt to verify minimal dependency compatibilityrequirements.txt for full functionality validationThe workflow saves the PR number as an artifact for downstream consumption by the copilot.yml workflow .github/workflows/unittest.yml37-46
Sources: .github/workflows/unittest.yml1-46
Review Flow: The copilot workflow downloads the PR number artifact from the unittest workflow, then fetches PR details and diff from GitHub. It processes the diff in chunks, sending each to g4f.ChatCompletion.create() for analysis. The AI returns structured JSON with line-by-line comments and markdown-formatted review summaries.
Sources: etc/tool/copilot.py1-256 .github/workflows/copilot.yml1-58
The copilot script uses two distinct prompt types and response parsers:
Code Analysis Prompt etc/tool/copilot.py154-188:
{"reviews": [{"line": <line_number>, "body": "<review comment>"}]}read_json() extracts JSON from markdown code blocks etc/tool/copilot.py59-77Review Summary Prompt etc/tool/copilot.py190-218:
read_text() extracts markdown etc/tool/copilot.py79-93AI Provider Configuration: The script uses environment variables G4F_PROVIDER and G4F_MODEL (defaults to gpt_4) for model selection etc/tool/copilot.py20-21 calling g4f.ChatCompletion.create() with ignore_stream_and_auth=True etc/tool/copilot.py106-111
Sources: etc/tool/copilot.py59-218
Conditional Review Strategy: The script checks if the PR already has reviews or comments etc/tool/copilot.py236-238 If it does, the new review is posted as a simple issue comment to avoid cluttering. For first-time reviews, it attempts to create a full review with inline comments via pull.create_review() etc/tool/copilot.py240-249
Sources: etc/tool/copilot.py220-253
Version Determination: The prepare job determines the version from the git tag, manual input, or defaults to 0.0.0-dev .github/workflows/build-packages.yml14-37 It sets two outputs: version and is_release (true only for tag pushes), which control whether Docker images are built and releases are created.
Sources: .github/workflows/build-packages.yml1-490
| Platform | Runner | Architectures | Build Tool | Output Artifacts |
|---|---|---|---|---|
| PyPI | ubuntu-latest | Platform-independent | python -m build | dist/*.whl, dist/*.tar.gz |
| Windows | windows-latest | x64 | Nuitka | g4f-windows-{version}-x64.zip |
| Linux | ubuntu-latest, ubuntu-24.04-arm | x64, arm64 | Nuitka | g4f-linux-{version}-{arch} |
| macOS | macos-latest | x64, arm64 | Nuitka | g4f-macos-{version}-{arch} |
| Docker | ubuntu-latest with QEMU | amd64, arm64, armv7 | Docker Buildx | Multiple tagged images |
Executable Build Process:
g4f_cli.py entry point with version pinned .github/workflows/build-packages.yml90-106 .github/workflows/build-packages.yml156-171scripts/build-nuitka.sh with environment variables G4F_VERSION, PLATFORM, ARCHITECTURE .github/workflows/build-packages.yml107-115Sources: .github/workflows/build-packages.yml40-237
Multi-Architecture Docker Images: The build-docker job only runs when is_release == 'true' .github/workflows/build-packages.yml240-243 and builds three image variants:
ARMv7 Image .github/workflows/build-packages.yml262-274:
docker/Dockerfile-armv7linux/arm/v7latest-armv7, {version}-armv7Slim Images .github/workflows/build-packages.yml275-287:
docker/Dockerfile-slimlinux/amd64, linux/arm64latest-slim, {version}-slimFull Image .github/workflows/build-packages.yml288-298:
docker/Dockerfilelinux/amd64docker/metadata-actionAll builds use QEMU for cross-platform compilation and push to Docker Hub (hlohaus789/g4f) with the version passed as a build arg.
Sources: .github/workflows/build-packages.yml240-298
Manifest Structure: The WinGet manifest consists of three YAML files generated dynamically .github/workflows/build-packages.yml334-409:
g4f.yaml): Package identifier and manifest versiong4f.installer.yaml):
zip with NestedInstallerType: portableg4fg4f.locale.en-US.yaml): Package metadata, description, tagsSources: .github/workflows/build-packages.yml334-409
Artifact Aggregation: The create-release job depends on all build jobs and only runs for tag pushes .github/workflows/build-packages.yml412-417 It performs the following:
./artifacts/ .github/workflows/build-packages.yml420-427softprops/action-gh-release@v2 .github/workflows/build-packages.yml428-471Release Assets: Files attached to the release include:
./artifacts/pypi-package/*)./artifacts/windows-exe-x64/*)Sources: .github/workflows/build-packages.yml412-471
The publish-to-pypi.yml workflow provides a separate, streamlined path for PyPI package distribution:
Trusted Publishing: The workflow uses GitHub's trusted publishing mechanism with OIDC tokens (id-token: write permission) rather than API keys .github/workflows/publish-to-pypi.yml39-43 This only runs when the repository is xtekky/gpt4free and a tag is pushed .github/workflows/publish-to-pypi.yml11
Environment Variable: The version is set via G4F_VERSION=${{ github.ref_name }} .github/workflows/publish-to-pypi.yml5-6 which is read during package build.
Sources: .github/workflows/publish-to-pypi.yml1-51
The test suite uses a consistent pattern for handling optional dependencies:
This pattern appears in etc/unittest/backend.py7-11 and etc/unittest/backend.py25-27 ensuring tests gracefully skip when dependencies like Flask GUI or search libraries are unavailable.
The TestBackendApi class uses unittest.mock.MagicMock to create a mock Flask app instance etc/unittest/backend.py28-29 allowing the Backend API to be tested without running a full Flask server.
Sources: etc/unittest/backend.py1-57
| Variable | Workflow | Purpose |
|---|---|---|
G4F_VERSION | build-packages, publish-to-pypi | Sets the package version during build |
GITHUB_TOKEN | All workflows | Authenticates with GitHub API |
GITHUB_REPOSITORY | copilot | Identifies the repository for PR operations |
G4F_PROVIDER | copilot | Specifies AI provider for code review |
G4F_MODEL | copilot | Specifies AI model for code review |
DOCKER_USERNAME | build-packages | Docker Hub authentication |
DOCKER_PASSWORD | build-packages | Docker Hub authentication |
PLATFORM | build-packages | Target platform for Nuitka builds |
ARCHITECTURE | build-packages | Target architecture for Nuitka builds |
Matrix Strategy: Build jobs use GitHub Actions matrix strategy to build for multiple architectures .github/workflows/build-packages.yml135-143:
This allows parallel execution of builds for different platforms while maintaining consistent build scripts.
Sources: .github/workflows/build-packages.yml1-490 etc/tool/copilot.py18-21
The close-inactive-issues.yml workflow uses the actions/stale@v10 action to automatically manage inactive issues and pull requests .github/workflows/close-inactive-issues.yml1-32:
Configuration:
"stale" for both issues and PRs"5 0 * * *")This helps maintain repository hygiene by closing inactive contributions that have not received responses.
Refresh this wiki