Skip to content

experiment/wip: feat(testing): seed test stacks from a db snapshot, faster boots #31275

experiment/wip: feat(testing): seed test stacks from a db snapshot, faster boots

experiment/wip: feat(testing): seed test stacks from a db snapshot, faster boots #31275

Workflow file for this run

---
# yamllint disable rule:truthy rule:line-length
name: "CI"
on:
pull_request:
push:
branches:
- develop
- stable
- release-*
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
env:
INFRAHUB_DB_USERNAME: neo4j
INFRAHUB_DB_PASSWORD: admin
INFRAHUB_DB_PROTOCOL: bolt
INFRAHUB_LOG_LEVEL: CRITICAL
INFRAHUB_IMAGE_NAME: "opsmill/infrahub"
INFRAHUB_IMAGE_VER: "local"
INFRAHUB_SERVER_PORT: 0
INFRAHUB_DB_BACKUP_PORT: 0
VMAGENT_PORT: 0
PYTEST_XDIST_WORKER_COUNT: 4
INFRAHUB_USE_TEST_CONTAINERS: 1
VALE_VERSION: "3.12.0"
GITHUB_PR_NUMBER: ${{ github.event.pull_request.number }}
METRICS_ENDPOINT: ${{ secrets.METRICS_ENDPOINT }}
jobs:
prepare-environment:
uses: ./.github/workflows/define-versions.yml
# ------------------------------------------ Check Files Changes ------------------------------------------
files-changed:
name: Detect which file has changed
runs-on: ubuntu-latest
timeout-minutes: 5
outputs:
backend: ${{ steps.changes.outputs.backend_all }}
documentation: ${{ steps.changes.outputs.documentation_all }}
documentation_generated: ${{ steps.changes.outputs.documentation_generated_all }}
release: ${{ steps.changes.outputs.release_all }}
frontend: ${{ steps.changes.outputs.frontend_all }}
e2e: ${{ steps.changes.outputs.e2e_all }}
python: ${{ steps.changes.outputs.python_all }}
javascript: ${{ steps.changes.outputs.javascript_all }}
yaml: ${{ steps.changes.outputs.yaml_all }}
infrahub_uv_files: ${{ steps.changes.outputs.infrahub_uv_files }}
github_workflows: ${{ steps.changes.outputs.github_workflows }}
version_upgrade_workflow: ${{ steps.changes.outputs.version_upgrade_workflow }}
e2e_tests: ${{ steps.changes.outputs.e2e_test_files }}
e2e_pytest_tests: ${{ steps.changes.outputs.e2e_pytest_test_files }}
testcontainers: ${{ steps.changes.outputs.testcontainers_files }}
openapi_schema: ${{ steps.changes.outputs.openapi_schema_all }}
graphql_schema: ${{ steps.changes.outputs.graphql_schema_all }}
error_catalogue: ${{ steps.changes.outputs.error_catalogue_all }}
dev_guidelines: ${{ steps.changes.outputs.dev_guidelines }}
observability_standalone: ${{ steps.changes.outputs.observability_standalone_all }}
steps:
- name: "Check out repository code"
uses: "actions/checkout@v7"
with:
submodules: true
- name: Check for file changes
uses: dorny/paths-filter@v4.0.2
id: changes
with:
token: ${{ github.token }}
filters: .github/file-filters.yml
# ------------------------------------------ All Linter ------------------------------------------
yaml-lint:
if: |
needs.files-changed.outputs.yaml == 'true' ||
needs.files-changed.outputs.infrahub_uv_files == 'true'
needs:
- files-changed
- prepare-environment
runs-on: "ubuntu-latest"
timeout-minutes: 5
steps:
- name: "Check out repository code"
uses: "actions/checkout@v7"
with:
submodules: true
- name: Set up Python
id: python
uses: actions/setup-python@v7
with:
python-version: ${{ needs.prepare-environment.outputs.PYTHON_VERSION }}
- name: Install uv
uses: astral-sh/setup-uv@v7
with:
version: ${{ needs.prepare-environment.outputs.UV_VERSION }}
- name: Install dependencies
run: "uv sync --all-groups"
- name: "Linting: yamllint"
run: "uv run yamllint -s ."
frontend-lint:
defaults:
run:
working-directory: ./frontend/app
runs-on: ubuntu-latest
permissions:
contents: read
steps:
- name: "Check out repository code"
uses: "actions/checkout@v7"
with:
submodules: true
- name: Set up Node.js
uses: actions/setup-node@v7
with:
node-version: 24
- name: Install pnpm
uses: pnpm/action-setup@v6
with:
version: 10
cache: true
cache_dependency_path: frontend/app/pnpm-lock.yaml
- name: Install dependencies
run: pnpm install --frozen-lockfile
- name: Check formatting and linting (Biome)
run: pnpm exec biome ci .
- name: Check unused exports (Knip)
run: pnpm knip
- name: Check TypeScript regressions (Betterer)
run: pnpm exec betterer ci
frontend-validate-openapi-types:
if: |
needs.files-changed.outputs.openapi_schema == 'true'
needs: ["files-changed"]
defaults:
run:
working-directory: ./frontend/app
runs-on: ubuntu-latest
permissions:
contents: read
timeout-minutes: 5
steps:
- name: "Check out repository code"
uses: "actions/checkout@v7"
- name: Setup Node.js
uses: actions/setup-node@v7
with:
node-version: 24
- name: Install pnpm
uses: pnpm/action-setup@v6
with:
version: 10
cache: true
cache_dependency_path: frontend/app/pnpm-lock.yaml
- name: Install dependencies
run: pnpm install --frozen-lockfile
- name: Generate OpenAPI types
run: pnpm codegen:openapi
- name: Check for uncommitted changes
run: |
if ! git diff --exit-code src/shared/api/rest/types.generated.ts; then
echo "❌ Error: Generated OpenAPI types are out of sync with schema/openapi.json"
echo ""
echo "The OpenAPI schema has been updated, but the generated TypeScript types haven't been regenerated."
echo ""
echo "To fix this, run the following commands from the repository root:"
echo " cd frontend/app"
echo " pnpm codegen:openapi"
echo " git add src/shared/api/rest/types.generated.ts"
echo " git commit -m 'chore: regenerate OpenAPI types'"
exit 1
fi
frontend-validate-error-catalogue:
if: |
needs.files-changed.outputs.error_catalogue == 'true'
needs: ["files-changed"]
defaults:
run:
working-directory: ./frontend/app
runs-on: ubuntu-latest
permissions:
contents: read
timeout-minutes: 5
steps:
- name: "Check out repository code"
uses: "actions/checkout@v7"
- name: Install pnpm
uses: pnpm/action-setup@v4
with:
version: 10
- name: Setup Node.js
uses: actions/setup-node@v7
with:
node-version: 24
cache: pnpm
cache-dependency-path: frontend/app/pnpm-lock.yaml
- name: Install dependencies
run: pnpm install --frozen-lockfile
- name: Verify generated error bindings match schema/error-catalogue.json
run: pnpm check:error-bindings
- name: Surface a remediation hint on failure
if: failure()
run: |
echo "❌ Error: Generated error bindings are out of sync with schema/error-catalogue.json"
echo ""
echo "The backend catalogue has been updated, but the frontend's typed mirror hasn't been regenerated."
echo ""
echo "To fix this, run the following commands from the repository root:"
echo " cd frontend/app"
echo " pnpm generate:error-bindings"
echo " git add src/shared/api/errors/catalogue.generated.ts"
echo " git commit -m 'chore: regenerate error bindings'"
frontend-validate-graphql-types:
if: |
needs.files-changed.outputs.graphql_schema == 'true'
needs: ["files-changed"]
defaults:
run:
working-directory: ./frontend/app
runs-on: ubuntu-latest
permissions:
contents: read
timeout-minutes: 5
steps:
- name: "Check out repository code"
uses: "actions/checkout@v7"
- name: Setup Node.js
uses: actions/setup-node@v7
with:
node-version: 24
- name: Install pnpm
uses: pnpm/action-setup@v6
with:
version: 10
cache: true
cache_dependency_path: frontend/app/pnpm-lock.yaml
- name: Install dependencies
run: pnpm install --frozen-lockfile
- name: Generate GraphQL types
run: pnpm codegen:graphql
- name: Check for uncommitted changes
run: |
if ! git diff --exit-code src/shared/api/graphql/generated/graphql-env.d.ts src/shared/api/graphql/generated/graphql-cache.d.ts; then
echo "❌ Error: Generated GraphQL types are out of sync"
echo ""
echo "The gql.tada generated files need to be regenerated."
echo ""
echo "To fix this, run the following commands from the repository root:"
echo " cd frontend/app"
echo " pnpm codegen:graphql"
echo " git add src/shared/api/graphql/generated/graphql-env.d.ts src/shared/api/graphql/generated/graphql-cache.d.ts"
echo " git commit -m 'chore: regenerate GraphQL types'"
exit 1
fi
validate-observability-standalone:
if: |
needs.files-changed.outputs.observability_standalone == 'true'
needs: ["files-changed", "prepare-environment"]
runs-on: ubuntu-latest
permissions:
contents: read
timeout-minutes: 5
steps:
- name: "Check out repository code"
uses: "actions/checkout@v7"
- name: Set up Python
uses: actions/setup-python@v7
with:
python-version: ${{ needs.prepare-environment.outputs.PYTHON_VERSION }}
- name: Install uv
uses: astral-sh/setup-uv@v7
with:
version: ${{ needs.prepare-environment.outputs.UV_VERSION }}
- name: Install dependencies
run: "uv sync --all-groups"
- name: Regenerate standalone compose file
working-directory: development
run: uv run python convert_compose_standalone.py
- name: Check for uncommitted changes
run: |
if ! git diff --exit-code development/docker-compose-observability-standalone.yml; then
echo "❌ Error: development/docker-compose-observability-standalone.yml is out of sync"
echo ""
echo "The observability source files have been updated, but the standalone compose file hasn't been regenerated."
echo ""
echo "To fix this, run the following commands from the repository root:"
echo " cd development"
echo " uv run python convert_compose_standalone.py"
echo " git add docker-compose-observability-standalone.yml"
echo " git commit -m 'chore: regenerate standalone observability compose'"
exit 1
fi
python-lint:
if: |
needs.files-changed.outputs.backend == 'true' ||
needs.files-changed.outputs.python == 'true'
needs:
- files-changed
- prepare-environment
runs-on: "ubuntu-latest"
timeout-minutes: 5
steps:
- name: "Check out repository code"
uses: "actions/checkout@v7"
with:
submodules: true
- name: Set up Python
id: python
uses: actions/setup-python@v7
with:
python-version: ${{ needs.prepare-environment.outputs.PYTHON_VERSION }}
- name: Install uv
uses: astral-sh/setup-uv@v7
with:
version: ${{ needs.prepare-environment.outputs.UV_VERSION }}
- name: Install dependencies
run: "uv sync --all-groups"
- name: "Linting: ruff check"
run: "uv run ruff check . --exclude python_sdk"
- name: "Linting: ruff format"
run: "uv run ruff format --check --diff --exclude python_sdk ."
- name: "Linting: ty check"
run: "uv run ty check ."
markdown-lint:
if: |
needs.files-changed.outputs.documentation == 'true' ||
needs.files-changed.outputs.release == 'true' ||
needs.files-changed.outputs.github_workflows
needs: ["files-changed"]
runs-on: "ubuntu-latest"
timeout-minutes: 5
steps:
- name: "Check out repository code"
uses: "actions/checkout@v7"
with:
submodules: true
- name: "Linting: markdownlint"
uses: DavidAnson/markdownlint-cli2-action@v24
with:
globs: "docs/docs/**/*.md docs/docs/**/*.mdx"
action-lint:
if: needs.files-changed.outputs.github_workflows == 'true'
needs: ["files-changed"]
runs-on: "ubuntu-latest"
timeout-minutes: 5
steps:
- name: "Check out repository code"
uses: "actions/checkout@v7"
with:
submodules: true
- name: Check workflow files
run: |
bash <(curl https://raw.githubusercontent.com/rhysd/actionlint/main/scripts/download-actionlint.bash)
./actionlint -color
shell: bash
env:
SHELLCHECK_OPTS: --exclude=SC2086 --exclude=SC2046 --exclude=SC2004 --exclude=SC2129
infrahub-uv-check:
if: |
needs.files-changed.outputs.infrahub_uv_files == 'true' ||
github.ref_name == 'stable' ||
github.ref_name == 'develop'
needs:
- "files-changed"
uses: "./.github/workflows/uv-check.yml"
with:
directory: "./"
infrahub-testcontainers-check:
if: needs.files-changed.outputs.infrahub_uv_files == 'true'
needs: ["prepare-environment", "files-changed"]
runs-on: ubuntu-latest
timeout-minutes: 5
steps:
- name: "Check out repository code"
uses: "actions/checkout@v7"
with:
submodules: true
- name: Set up Python
id: python
uses: actions/setup-python@v7
with:
python-version: ${{ needs.prepare-environment.outputs.PYTHON_VERSION }}
- name: Install uv
uses: astral-sh/setup-uv@v7
with:
version: ${{ needs.prepare-environment.outputs.UV_VERSION }}
- name: Install dependencies
run: "uv sync --all-groups"
- name: Compare package versions
run: |
INFRAHUB_VERSION=$(uv version --short)
echo "Infrahub version: $INFRAHUB_VERSION"
cd python_testcontainers
TESTCONTAINERS_VERSION=$(uv version --short)
echo "Testcontainers version: $TESTCONTAINERS_VERSION"
if [ "$INFRAHUB_VERSION" != "$TESTCONTAINERS_VERSION" ]; then
echo "Error: Version mismatch!"
echo "infrahub version: $INFRAHUB_VERSION"
echo "infrahub-testcontainers version: $TESTCONTAINERS_VERSION"
echo "The version of infrahub-testcontainers must match the version of infrahub"
exit 1
fi
backend-testcontainers-unit:
if: |
always() && !cancelled() &&
!contains(needs.*.result, 'failure') &&
!contains(needs.*.result, 'cancelled') &&
(
needs.files-changed.outputs.testcontainers == 'true' ||
needs.files-changed.outputs.github_workflows == 'true'
)
needs: ["prepare-environment", "files-changed", "yaml-lint", "python-lint"]
strategy:
matrix:
python-version:
- "3.10"
- "3.11"
- "3.12"
- "3.13"
- "3.14"
runs-on: ubuntu-latest
timeout-minutes: 30
defaults:
run:
working-directory: ./python_testcontainers
steps:
- name: "Check out repository code"
uses: "actions/checkout@v7"
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v7
with:
python-version: ${{ matrix.python-version }}
- name: Install uv
uses: astral-sh/setup-uv@v7
with:
version: ${{ needs.prepare-environment.outputs.UV_VERSION }}
- name: Install dependencies
run: "uv sync --all-groups"
- name: "Unit Tests"
run: "uv run pytest --rootdir=. -c pyproject.toml -vs tests"
infrahub-testcontainers-uv-check:
if: |
needs.files-changed.outputs.infrahub_uv_files == 'true' ||
github.ref_name == 'stable' ||
github.ref_name == 'develop'
needs:
- "files-changed"
uses: "./.github/workflows/uv-check.yml"
with:
directory: "./python_testcontainers"
backend-tests-unit:
if: |
always() && !cancelled() &&
!contains(needs.*.result, 'failure') &&
!contains(needs.*.result, 'cancelled') &&
needs.files-changed.outputs.backend == 'true'
needs: ["prepare-environment", "files-changed", "yaml-lint", "python-lint", "infrahub-testcontainers-check"]
strategy:
fail-fast: false
matrix:
python-version:
- "3.12"
- "3.13"
- "3.14"
runs-on: ubuntu-latest
timeout-minutes: 5
steps:
- name: "Check out repository code"
uses: "actions/checkout@v7"
with:
submodules: true
- name: Set up Python ${{ matrix.python-version }}
id: python
uses: actions/setup-python@v7
with:
python-version: ${{ matrix.python-version }}
- name: Install uv
uses: astral-sh/setup-uv@v7
with:
version: ${{ needs.prepare-environment.outputs.UV_VERSION }}
- name: Install dependencies
run: "uv sync --all-groups"
- name: "Unit Tests"
run: "uv run invoke backend.test-unit"
- name: "Coveralls : Unit Tests"
if: matrix.python-version == '3.13'
uses: coverallsapp/github-action@v2
continue-on-error: true
env:
COVERALLS_SERVICE_NUMBER: ${{ github.sha }}
with:
flag-name: backend-unit
parallel: true
backend-tests-component:
if: |
always() && !cancelled() &&
!contains(needs.*.result, 'failure') &&
!contains(needs.*.result, 'cancelled') &&
needs.files-changed.outputs.backend == 'true'
needs: ["prepare-environment", "files-changed", "yaml-lint", "python-lint", "infrahub-testcontainers-check"]
strategy:
fail-fast: false
matrix:
shard:
- "graphql"
- "core-diff"
- "core-schema"
- "other"
runs-on:
group: huge-runners
timeout-minutes: 45
env:
INFRAHUB_DB_TYPE: neo4j
PYTEST_XDIST_WORKER_COUNT: 2
steps:
- name: "Check out repository code"
uses: "actions/checkout@v7"
with:
submodules: true
- name: Set up Python
id: python
uses: actions/setup-python@v7
with:
python-version: ${{ needs.prepare-environment.outputs.PYTHON_VERSION }}
- name: "Setup git credentials"
run: "git config --global user.name 'Infrahub' && \
git config --global user.email 'infrahub@opsmill.com' && \
git config --global --add safe.directory '*' && \
git config --global credential.usehttppath true && \
git config --global credential.helper '/usr/bin/env infrahub-git-credential'"
- name: Install uv
uses: astral-sh/setup-uv@v7
with:
version: ${{ needs.prepare-environment.outputs.UV_VERSION }}
- name: Install dependencies
run: "uv sync --all-groups"
- name: "Validate component test shards"
if: matrix.shard == 'other'
run: "uv run invoke backend.validate-component-shards"
- name: "Component Tests (${{ matrix.shard }})"
run: "uv run invoke backend.test-component --shard ${{ matrix.shard }}"
- name: "Coveralls : Component Tests"
uses: coverallsapp/github-action@v2
continue-on-error: true
env:
COVERALLS_SERVICE_NUMBER: ${{ github.sha }}
with:
flag-name: backend-component-${{ matrix.shard }}
parallel: true
# - name: Generate tracing spans
# if: always() && github.event.pull_request.head.repo.fork == false && github.actor != 'dependabot[bot]'
# uses: inception-health/otel-upload-test-artifact-action@v1
# with:
# jobName: "backend-tests-unit"
# stepName: "Unit Tests"
# path: "pytest-junit.xml"
# type: "junit"
# githubToken: ${{ secrets.GH_TRACING_REPO_TOKEN }}
backend-validate-db-snapshot:
if: |
always() && !cancelled() &&
!contains(needs.*.result, 'failure') &&
!contains(needs.*.result, 'cancelled') &&
needs.files-changed.outputs.backend == 'true'
needs: ["prepare-environment", "files-changed", "yaml-lint", "python-lint", "infrahub-testcontainers-check"]
runs-on: ubuntu-24.04
timeout-minutes: 20
env:
INFRAHUB_DB_TYPE: neo4j
steps:
- name: "Check out repository code"
uses: "actions/checkout@v7"
with:
submodules: true
- name: Set up Python
id: python
uses: actions/setup-python@v6
with:
python-version: ${{ needs.prepare-environment.outputs.PYTHON_VERSION }}
- name: Install uv
uses: astral-sh/setup-uv@v7
with:
version: ${{ needs.prepare-environment.outputs.UV_VERSION }}
- name: Install dependencies
run: "uv sync --all-groups"
# Fails if the committed snapshot no longer matches a freshly generated one (e.g. after a
# schema/menu/permission change). Regenerate with:
# infrahub db snapshot-dump backend/tests/fixtures/db_snapshots/core_bootstrap.json.gz
- name: "Validate database snapshot freshness"
run: "uv run pytest backend/tests/component/database/test_snapshot.py -q"
backend-tests-integration:
if: |
always() && !cancelled() &&
!contains(needs.*.result, 'failure') &&
!contains(needs.*.result, 'cancelled') &&
needs.files-changed.outputs.backend == 'true'
needs: ["prepare-environment", "files-changed", "yaml-lint", "python-lint", "infrahub-testcontainers-check"]
runs-on:
group: "huge-runners"
timeout-minutes: 30
env:
INFRAHUB_DB_TYPE: neo4j
steps:
- name: "Check out repository code"
uses: "actions/checkout@v7"
with:
submodules: true
- name: Set up Python
id: python
uses: actions/setup-python@v7
with:
python-version: ${{ needs.prepare-environment.outputs.PYTHON_VERSION }}
- name: "Setup git credentials"
run: "git config --global user.name 'Infrahub' && \
git config --global user.email 'infrahub@opsmill.com' && \
git config --global --add safe.directory '*' && \
git config --global credential.usehttppath true && \
git config --global credential.helper '/usr/bin/env infrahub-git-credential'"
- name: Install uv
uses: astral-sh/setup-uv@v7
with:
version: ${{ needs.prepare-environment.outputs.UV_VERSION }}
- name: Install dependencies
run: "uv sync --all-groups"
- name: "Mypy Tests"
run: "uv run invoke backend.mypy"
- name: "Integration Tests"
run: "uv run invoke backend.test-integration"
- name: "Coveralls : Integration Tests"
uses: coverallsapp/github-action@v2
continue-on-error: true
env:
COVERALLS_SERVICE_NUMBER: ${{ github.sha }}
with:
flag-name: backend-integration
parallel: true
backend-tests-functional:
if: |
always() && !cancelled() &&
!contains(needs.*.result, 'failure') &&
!contains(needs.*.result, 'cancelled') &&
needs.files-changed.outputs.backend == 'true'
needs: ["prepare-environment", "files-changed", "yaml-lint", "python-lint", "infrahub-testcontainers-check"]
runs-on:
group: "huge-runners"
timeout-minutes: 30
env:
INFRAHUB_DB_TYPE: neo4j
steps:
- name: "Check out repository code"
uses: "actions/checkout@v7"
with:
submodules: true
- name: Set up Python
id: python
uses: actions/setup-python@v7
with:
python-version: ${{ needs.prepare-environment.outputs.PYTHON_VERSION }}
- name: "Setup git credentials"
run: "git config --global user.name 'Infrahub' && \
git config --global user.email 'infrahub@opsmill.com' && \
git config --global --add safe.directory '*' && \
git config --global credential.usehttppath true && \
git config --global credential.helper '/usr/bin/env infrahub-git-credential'"
- name: Install uv
uses: astral-sh/setup-uv@v7
with:
version: ${{ needs.prepare-environment.outputs.UV_VERSION }}
- name: Install dependencies
run: "uv sync --all-groups"
- name: "Mypy Tests"
run: "uv run invoke backend.mypy"
- name: "Functional Tests"
run: "uv run invoke backend.test-functional"
- name: "Coveralls : Functional Tests"
uses: coverallsapp/github-action@v2
continue-on-error: true
env:
COVERALLS_SERVICE_NUMBER: ${{ github.sha }}
with:
flag-name: backend-functional
parallel: true
backend-docker-integration:
if: |
always() && !cancelled() &&
!contains(needs.*.result, 'failure') &&
!contains(needs.*.result, 'cancelled') &&
(needs.files-changed.outputs.backend == 'true' ||
needs.files-changed.outputs.testcontainers == 'true')
needs: ["prepare-environment", "files-changed", "yaml-lint", "python-lint"]
runs-on:
group: huge-runners
timeout-minutes: 45
env:
INFRAHUB_DB_TYPE: neo4j
PYTEST_XDIST_WORKER_COUNT: 1
UV_VERSION: ${{ needs.prepare-environment.outputs.UV_VERSION }}
steps:
- name: "Check out repository code"
uses: "actions/checkout@v7"
with:
submodules: true
- name: Set up Python
id: python
uses: actions/setup-python@v7
with:
python-version: ${{ needs.prepare-environment.outputs.PYTHON_VERSION }}
- name: Install tini
run: "apt-get update && apt-get install -y tini"
- name: "Setup git credentials"
run: "git config --global user.name 'Infrahub' && \
git config --global user.email 'infrahub@opsmill.com' && \
git config --global --add safe.directory '*' && \
git config --global credential.usehttppath true && \
git config --global credential.helper '/usr/bin/env infrahub-git-credential'"
- name: "Set environment variables"
run: echo INFRAHUB_BUILD_NAME=infrahub-${{ runner.name }}>> $GITHUB_ENV
- name: "Set environment variables"
run: |
RUNNER_NAME=$(echo "${{ runner.name }}" | grep -o 'ghrunner[0-9]\+' | sed 's/ghrunner\([0-9]\+\)/ghrunner_\1/')
echo "PYTEST_DEBUG_TEMPROOT=/var/lib/github/${RUNNER_NAME}/_temp" >> $GITHUB_ENV
echo INFRAHUB_IMAGE_VER=local-${{ runner.name }}-${{ github.sha }} >> $GITHUB_ENV
echo INFRAHUB_TESTING_IMAGE_VER=local-${{ runner.name }}-${{ github.sha }} >> $GITHUB_ENV
echo INFRAHUB_TESTING_DOCKER_IMAGE="opsmill/infrahub" >> $GITHUB_ENV
- name: Install uv
uses: astral-sh/setup-uv@v7
with:
version: ${{ needs.prepare-environment.outputs.UV_VERSION }}
- name: Install dependencies
run: "uv sync --all-groups"
- name: "Build container"
run: "uv run invoke dev.build"
- name: "Run tests"
# Use tini to properly propagate cancellation signal to pytest, so that containers are properly destroyed
run: "exec tini -s -g -- uv run pytest backend/tests/integration_docker/"
# ---------------------------------------------------
# DISABLING Memgraph for now :(
# Tests where too flaky in 2.19 and completely broken in 2.20.1
# ---------------------------------------------------
# backend-tests-memgraph:
# if: |
# always() && !cancelled() &&
# !contains(needs.*.result, 'failure') &&
# !contains(needs.*.result, 'cancelled') &&
# needs.files-changed.outputs.backend == 'true'
# needs: ["prepare-environment", "files-changed", "yaml-lint", "python-lint"]
# runs-on:
# group: huge-runners
# timeout-minutes: 45
# strategy:
# fail-fast: false
# matrix:
# include:
# - name: backend-tests-unit-memgraph
# env:
# INFRAHUB_DB_TYPE: memgraph
# # - name: backend-tests-unit-nats
# # env:
# # INFRAHUB_DB_TYPE: memgraph
# # INFRAHUB_USE_NATS: 1
# # INFRAHUB_BROKER_DRIVER: nats
# # INFRAHUB_CACHE_DRIVER: nats
# name: ${{ matrix.name }}
# env: ${{ matrix.env }}
# steps:
# - name: "Check out repository code"
# uses: "actions/checkout@v7"
# with:
# submodules: true
# - name: Set up Python
# uses: actions/setup-python@v7
# with:
# python-version: ${{ needs.prepare-environment.outputs.PYTHON_VERSION }}
# - name: "Setup git credentials"
# run: "git config --global user.name 'Infrahub' && \
# git config --global user.email 'infrahub@opsmill.com' && \
# git config --global --add safe.directory '*' && \
# git config --global credential.usehttppath true && \
# git config --global credential.helper '/usr/bin/env infrahub-git-credential'"
# - name: Install uv
# uses: astral-sh/setup-uv@v7
# with:
# version: ${{ needs.prepare-environment.outputs.UV_VERSION }}
# - name: Install dependencies
# run: "uv sync --all-groups"
# - name: "Unit Tests"
# run: "uv run invoke backend.test-unit"
backend-validate-generated:
if: |
always() && !cancelled() &&
!contains(needs.*.result, 'failure') &&
!contains(needs.*.result, 'cancelled') &&
(needs.files-changed.outputs.backend == 'true' ||
needs.files-changed.outputs.documentation == 'true')
needs: ["prepare-environment", "files-changed", "yaml-lint", "python-lint", "infrahub-testcontainers-check"]
runs-on: ubuntu-latest
steps:
- name: Check out repository code
uses: actions/checkout@v7
with:
submodules: true
- name: Set up Python
id: python
uses: actions/setup-python@v7
with:
python-version: ${{ needs.prepare-environment.outputs.PYTHON_VERSION }}
- name: Install uv
uses: astral-sh/setup-uv@v7
with:
version: ${{ needs.prepare-environment.outputs.UV_VERSION }}
- name: Install dependencies
run: "uv sync --all-groups"
- name: "Run validator"
run: "uv run invoke backend.validate-generated"
frontend-tests:
if: |
always() && !cancelled() &&
!contains(needs.*.result, 'failure') &&
!contains(needs.*.result, 'cancelled') &&
needs.files-changed.outputs.frontend == 'true'
needs: ["files-changed", "yaml-lint", "frontend-lint"]
runs-on: "ubuntu-22.04"
timeout-minutes: 30
steps:
- name: "Check out repository code"
uses: "actions/checkout@v7"
with:
submodules: true
- name: Install NodeJS
uses: actions/setup-node@v7
with:
# https://github.com/microsoft/playwright/issues/41000
node-version: 24.15.0
- name: Install pnpm
uses: pnpm/action-setup@v6
with:
version: 10
cache: true
cache_dependency_path: frontend/app/pnpm-lock.yaml
- name: "Install frontend"
working-directory: ./frontend/app
run: pnpm install --frozen-lockfile
- name: Install Playwright Browsers
working-directory: ./frontend/app
run: pnpm exec playwright install chromium
- name: "Run unit tests"
working-directory: ./frontend/app
run: "pnpm test:coverage"
- name: "Coveralls : Unit Tests"
uses: coverallsapp/github-action@v2
continue-on-error: true
env:
COVERALLS_SERVICE_NUMBER: ${{ github.sha }}
with:
flag-name: frontend-unit
parallel: true
file: frontend/app/coverage/lcov.info
graphql-schema:
if: |
always() && !cancelled() &&
!contains(needs.*.result, 'failure') &&
!contains(needs.*.result, 'cancelled') &&
needs.files-changed.outputs.backend == 'true'
needs: ["prepare-environment", "files-changed", "yaml-lint", "python-lint"]
runs-on: "ubuntu-22.04"
steps:
- name: Check out repository code
uses: "actions/checkout@v7"
with:
submodules: true
- name: Set up Python
id: python
uses: actions/setup-python@v7
with:
python-version: ${{ needs.prepare-environment.outputs.PYTHON_VERSION }}
- name: Install uv
uses: astral-sh/setup-uv@v7
with:
version: ${{ needs.prepare-environment.outputs.UV_VERSION }}
- name: Install dependencies
run: "uv sync --all-groups"
- name: Run validation
run: uv run invoke schema.validate-graphqlschema
json-schema:
if: |
always() && !cancelled() &&
!contains(needs.*.result, 'failure') &&
!contains(needs.*.result, 'cancelled') &&
needs.files-changed.outputs.backend == 'true'
needs: ["prepare-environment", "files-changed", "yaml-lint", "python-lint"]
runs-on: "ubuntu-22.04"
steps:
- name: Check out repository code
uses: "actions/checkout@v7"
with:
submodules: true
- name: Set up Python
id: python
uses: actions/setup-python@v7
with:
python-version: ${{ needs.prepare-environment.outputs.PYTHON_VERSION }}
- name: Install uv
uses: astral-sh/setup-uv@v7
with:
version: ${{ needs.prepare-environment.outputs.UV_VERSION }}
- name: Install dependencies
run: "uv sync --all-groups"
- name: Run validation
run: uv run invoke schema.validate-jsonschema
validate-docker-compose-env-vars:
if: |
always() && !cancelled() &&
!contains(needs.*.result, 'failure') &&
!contains(needs.*.result, 'cancelled') &&
needs.files-changed.outputs.backend == 'true'
needs: ["prepare-environment", "files-changed", "yaml-lint", "python-lint"]
runs-on: "ubuntu-22.04"
steps:
- name: Check out repository code
uses: "actions/checkout@v7"
with:
submodules: true
- name: Set up Python
id: python
uses: actions/setup-python@v7
with:
python-version: ${{ needs.prepare-environment.outputs.PYTHON_VERSION }}
- name: Install uv
uses: astral-sh/setup-uv@v7
with:
version: ${{ needs.prepare-environment.outputs.UV_VERSION }}
- name: Install dependencies
run: "uv sync --all-groups"
- name: Run validation
run: uv run invoke release.validate-dockercomposeenv
documentation:
defaults:
run:
working-directory: ./docs
if: |
always() && !cancelled() &&
!contains(needs.*.result, 'failure') &&
!contains(needs.*.result, 'cancelled') &&
(needs.files-changed.outputs.release == 'true') || (needs.files-changed.outputs.documentation == 'true')
needs: ["prepare-environment", "files-changed", "yaml-lint", "python-lint", "infrahub-testcontainers-check"]
runs-on: "ubuntu-22.04"
timeout-minutes: 5
steps:
- name: "Check out repository code"
uses: "actions/checkout@v7"
with:
submodules: true
- name: Install NodeJS
uses: actions/setup-node@v7
with:
node-version: 24
cache: 'npm'
cache-dependency-path: docs/package-lock.json
- name: Set up Python
id: python
uses: actions/setup-python@v7
with:
python-version: ${{ needs.prepare-environment.outputs.PYTHON_VERSION }}
- name: Install uv
uses: astral-sh/setup-uv@v7
with:
version: ${{ needs.prepare-environment.outputs.UV_VERSION }}
- name: Install dependencies
run: "uv sync --all-groups"
- name: "Install npm dependencies"
working-directory: ./docs
run: npm install
- name: "Build docs"
run: "uv run invoke docs.build"
validate-generated-documentation:
if: |
always() && !cancelled() &&
!contains(needs.*.result, 'failure') &&
!contains(needs.*.result, 'cancelled') &&
(needs.files-changed.outputs.python == 'true' ||
needs.files-changed.outputs.documentation == 'true')
needs: ["prepare-environment", "files-changed", "yaml-lint", "python-lint", "infrahub-testcontainers-check"]
runs-on: "ubuntu-22.04"
timeout-minutes: 5
steps:
- name: "Check out repository code"
uses: "actions/checkout@v7"
with:
submodules: true
- name: Install NodeJS
uses: actions/setup-node@v7
with:
node-version: 24
cache: 'npm'
cache-dependency-path: docs/package-lock.json
- name: Set up Python
id: python
uses: actions/setup-python@v7
with:
python-version: ${{ needs.prepare-environment.outputs.PYTHON_VERSION }}
- name: Install uv
uses: astral-sh/setup-uv@v7
with:
version: ${{ needs.prepare-environment.outputs.UV_VERSION }}
- name: Install dependencies
run: "uv sync --all-groups"
- name: "Validate generated documentation"
run: "uv run invoke docs.validate"
validate-dev-guideline-links:
if: |
always() && !cancelled() &&
!contains(needs.*.result, 'failure') &&
!contains(needs.*.result, 'cancelled') &&
(needs.files-changed.outputs.python == 'true') ||
(needs.files-changed.outputs.dev_guidelines == 'true') ||
(needs.files-changed.outputs.javascript == 'true') ||
(needs.files-changed.outputs.github_workflows == 'true')
needs: ["prepare-environment", "files-changed", "yaml-lint", "python-lint", "infrahub-testcontainers-check"]
runs-on: "ubuntu-24.04"
timeout-minutes: 5
steps:
- name: "Check out repository code"
uses: "actions/checkout@v7"
with:
submodules: true
- name: Check links
uses: lycheeverse/lychee-action@v2
with:
args: |
--no-progress
--config dev/lychee.toml
--files-from dev/lychee-files.txt
fail: true
validate-documentation-style:
if: |
always() && !cancelled() &&
!contains(needs.*.result, 'failure') &&
!contains(needs.*.result, 'cancelled') &&
(needs.files-changed.outputs.release == 'true' ||
needs.files-changed.outputs.documentation == 'true')
needs: ["files-changed", "yaml-lint", "python-lint", "infrahub-testcontainers-check"]
runs-on: "ubuntu-22.04"
timeout-minutes: 5
steps:
- name: "Check out repository code"
uses: "actions/checkout@v7"
with:
submodules: true
# The official GitHub Action for Vale doesn't work, installing manually instead:
# https://github.com/errata-ai/vale-action/issues/103
- name: Download Vale
run: |
curl -sL "https://github.com/errata-ai/vale/releases/download/v${VALE_VERSION}/vale_${VALE_VERSION}_Linux_64-bit.tar.gz" -o vale.tar.gz
tar -xzf vale.tar.gz
env:
VALE_VERSION: ${{ env.VALE_VERSION }}
- name: "Validate documentation style"
run: ./vale --config=./.vale.ini $(find ./docs -type f \( -name "*.mdx" -o -name "*.md" \) -not -path "./docs/node_modules/*")
validate-release-notes-style:
if: |
always() && !cancelled() &&
!contains(needs.*.result, 'failure') &&
!contains(needs.*.result, 'cancelled') &&
needs.files-changed.outputs.release == 'true'
needs: ["files-changed", "yaml-lint", "python-lint", "infrahub-testcontainers-check"]
runs-on: "ubuntu-22.04"
timeout-minutes: 5
steps:
- name: "Check out repository code"
uses: "actions/checkout@v7"
with:
submodules: true
# The official GitHub Action for Vale doesn't work, installing manually instead:
# https://github.com/errata-ai/vale-action/issues/103
- name: Download Vale
run: |
curl -sL "https://github.com/errata-ai/vale/releases/download/v${VALE_VERSION}/vale_${VALE_VERSION}_Linux_64-bit.tar.gz" -o vale.tar.gz
tar -xzf vale.tar.gz
env:
VALE_VERSION: ${{ env.VALE_VERSION }}
- name: "Validate release notes style"
run: ./vale --config=./.vale.ini $(find ./changelog ./docs/docs/release-notes/infrahub -type f \( -name '*.mdx' -o -name '*.md' \)) CHANGELOG.md
# ------------------------------------------ E2E Tests ------------------------------------------
E2E-testing-playwright:
defaults:
run:
working-directory: ./frontend/app
needs:
- prepare-environment
- frontend-lint
- files-changed
- yaml-lint
- python-lint
- infrahub-testcontainers-check
if: |
always() && !cancelled() &&
!contains(needs.*.result, 'failure') &&
!contains(needs.*.result, 'cancelled') &&
needs.files-changed.outputs.e2e == 'true'
runs-on:
group: huge-runners
timeout-minutes: 60
strategy:
fail-fast: false
matrix:
include:
- name: E2E-testing-playwright
env:
INFRAHUB_DB_TYPE: neo4j
UV_VERSION: ${{ needs.prepare-environment.outputs.UV_VERSION }}
# - name: E2E-testing-playwright-nats
# env:
# INFRAHUB_DB_TYPE: neo4j
# INFRAHUB_USE_NATS: 1
# INFRAHUB_BROKER_DRIVER: nats
# INFRAHUB_BROKER_PORT: 4222
# INFRAHUB_CACHE_DRIVER: nats
# INFRAHUB_CACHE_ADDRESS: message-queue
# INFRAHUB_CACHE_PORT: 4222
name: ${{ matrix.name }}
env: ${{ matrix.env }}
steps:
- name: Check out repository code
uses: actions/checkout@v7
with:
submodules: true
- name: Install NodeJS
uses: actions/setup-node@v7
with:
node-version: 24
- name: Install pnpm
uses: pnpm/action-setup@v6
with:
version: 10
cache: true
cache_dependency_path: frontend/app/pnpm-lock.yaml
- name: Set up Python
id: python
uses: actions/setup-python@v7
with:
python-version: ${{ needs.prepare-environment.outputs.PYTHON_VERSION }}
- name: Install uv
uses: astral-sh/setup-uv@v7
with:
version: ${{ needs.prepare-environment.outputs.UV_VERSION }}
- name: Install dependencies
run: "uv sync --all-groups"
- name: Set job name
run: echo JOB_NAME="$GITHUB_JOB" >> $GITHUB_ENV
- name: Enable tracing
if: github.event.pull_request.head.repo.fork == false && github.actor != 'dependabot[bot]'
run: echo "INFRAHUB_TRACE_ENABLE=true" >> $GITHUB_ENV
- name: Set tracing configuration
run: echo "INFRAHUB_TRACE_INSECURE=false" >> $GITHUB_ENV
- name: Set tracing configuration
run: echo "INFRAHUB_TRACE_EXPORTER_TYPE=otlp" >> $GITHUB_ENV
- name: Set tracing configuration
run: echo "INFRAHUB_TRACE_EXPORTER_ENDPOINT=${{ secrets.TRACING_ENDPOINT }}" >> $GITHUB_ENV
- name: Set tracing configuration
run: echo "OTEL_RESOURCE_ATTRIBUTES=github.run_id=${GITHUB_RUN_ID}" >> $GITHUB_ENV
- name: "Store start time"
run: echo TEST_START_TIME=$(date +%s)000 >> $GITHUB_ENV
- name: "Set environment variables"
run: echo INFRAHUB_BUILD_NAME=infrahub-${{ runner.name }} >> $GITHUB_ENV
- name: "Set environment variables"
run: echo INFRAHUB_IMAGE_VER=local-${{ runner.name }}-${{ github.sha }} >> $GITHUB_ENV
- name: "Clear docker environment"
run: docker compose -p $INFRAHUB_BUILD_NAME down -v --remove-orphans --rmi local
- name: Build Demo
run: |
echo "::group::Build infrahub container"
uv run invoke dev.build
echo "::endgroup::"
- name: Initialize Demo
id: init-demo
run: uv run invoke dev.start dev.load-infra-schema
- name: Check Demo Status
run: uv run invoke dev.status
- name: Load Data
run: uv run invoke dev.load-infra-data
- name: Git Repository
run: uv run invoke dev.infra-git-import dev.infra-git-create
- name: Set infrahub address
run: |
PORT=$(docker compose -p $INFRAHUB_BUILD_NAME port server 8000 | cut -d: -f2)
echo "INFRAHUB_ADDRESS=http://localhost:${PORT}" >> $GITHUB_ENV
- name: Install frontend dependencies
run: pnpm install --frozen-lockfile
- name: Install Playwright Browsers
run: pnpm exec playwright install chromium --no-shell
# Make chromium ignore netlink messages so AddressTrackerLinux takes its "assume always
# online" path. The LD_PRELOAD shim fails NETLINK_ROUTE sockets at the libc level, which
# is robust across Playwright/Chromium versions (unlike patching the chrome binary). The
# shim is injected into the browser process via playwright.config.ts (NO_NETLINK_SO).
- name: Build no-netlink shim
run: |
gcc -shared -fPIC -Wall -Wextra \
-o "$RUNNER_TEMP/no_netlink.so" \
tests/e2e/fixtures/no_netlink.c -ldl
echo "NO_NETLINK_SO=$RUNNER_TEMP/no_netlink.so" >> "$GITHUB_ENV"
- name: Wait for artifacts to be generated before restarting infrahub
if: needs.files-changed.outputs.e2e_tests == 'true'
run: pnpm exec playwright test artifact
- name: Add response delay if required
if: needs.files-changed.outputs.e2e_tests == 'true'
run: echo "INFRAHUB_MISC_RESPONSE_DELAY=1" >> $GITHUB_ENV && uv run invoke dev.start
env:
INFRAHUB_MISC_RESPONSE_DELAY: 1
- name: Set infrahub address
if: needs.files-changed.outputs.e2e_tests == 'true'
run: |
PORT=$(docker compose -p $INFRAHUB_BUILD_NAME port server 8000 | cut -d: -f2)
echo "INFRAHUB_ADDRESS=http://localhost:${PORT}" >> $GITHUB_ENV
- name: Run Playwright tests
run: pnpm ci:test:e2e
# - name: Generate tracing spans
# if: always() && github.event.pull_request.head.repo.fork == false && github.actor != 'dependabot[bot]'
# uses: inception-health/otel-upload-test-artifact-action@v1
# with:
# jobName: "E2E-testing-playwright"
# stepName: "Run Playwright tests"
# path: "frontend/app/playwright-junit.xml"
# type: "junit"
# githubToken: ${{ secrets.GH_TRACING_REPO_TOKEN }}
- name: playwright-report
if: always()
uses: actions/upload-artifact@v7
with:
name: ${{ matrix.name }}
path: frontend/app/playwright-report/
- name: Containers after tests
if: always()
run: docker ps -a
- name: Display server logs
if: always()
run: docker logs "${INFRAHUB_BUILD_NAME}-server-1" || true
- name: Display task worker 1 logs
if: always()
run: docker logs "${INFRAHUB_BUILD_NAME}-task-worker-1" || true
- name: Display task worker 2 logs
if: always()
run: docker logs "${INFRAHUB_BUILD_NAME}-task-worker-2" || true
- name: Display task manager logs
if: always()
run: docker logs "${INFRAHUB_BUILD_NAME}-task-manager-1" || true
- name: Display database logs
if: always()
run: docker logs "${INFRAHUB_BUILD_NAME}-database-1" || true
- name: Display message-queue logs
if: always()
run: docker logs "${INFRAHUB_BUILD_NAME}-message-queue-1" || true
- name: Display server status
if: always()
run: uv run invoke demo.status
- name: "Clear docker environment and force vmagent to stop"
if: always()
run: docker compose -p $INFRAHUB_BUILD_NAME down -v --remove-orphans --rmi local
- name: "Wait for vmagent to push metrics"
if: always()
run: "sleep 10"
- name: "Show graph URL"
if: always()
run: 'echo "https://grafana-prod.tailc018d.ts.net/d/a4461039-bb27-4f57-9b2a-2c7f4e0a3459/e2e-tests?orgId=1&var-pr=$GITHUB_PR_NUMBER&var-job=$JOB_NAME&var-runner=$INFRAHUB_BUILD_NAME&from=$TEST_START_TIME&to=$(date +%s)000"'
# ----------------------------- E2E pytest-playwright (infrahub-testcontainers) -----------------------------
# New Python e2e suite. Runs ALONGSIDE E2E-testing-playwright (the TS suite)
# until parity is confirmed, then the TS job can be removed. Instead of
# `invoke dev.start dev.load-infra-*`, infrahub-testcontainers spins up the
# stack and pytest fixtures load the dataset (see tests/e2e/).
E2E-testing-pytest-playwright:
needs:
- prepare-environment
- files-changed
- yaml-lint
- python-lint
- infrahub-testcontainers-check
if: |
always() && !cancelled() &&
!contains(needs.*.result, 'failure') &&
!contains(needs.*.result, 'cancelled') &&
needs.files-changed.outputs.e2e == 'true'
runs-on:
group: huge-runners
timeout-minutes: 60
strategy:
fail-fast: false
matrix:
shard: [foundation, sites_a, sites_b, branches_repo, tutorial]
env:
INFRAHUB_DB_TYPE: neo4j
UV_VERSION: ${{ needs.prepare-environment.outputs.UV_VERSION }}
PYTEST_XDIST_WORKER_COUNT: 1
steps:
- name: Check out repository code
uses: actions/checkout@v7
with:
submodules: true
- name: Set up Python
id: python
uses: actions/setup-python@v7
with:
python-version: ${{ needs.prepare-environment.outputs.PYTHON_VERSION }}
- name: Install uv
uses: astral-sh/setup-uv@v7
with:
version: ${{ needs.prepare-environment.outputs.UV_VERSION }}
- name: Install dependencies
run: "uv sync --all-groups"
- name: Install Playwright browsers
run: uv run playwright install --with-deps chromium
- name: Install tini
run: apt-get update && apt-get install -y tini
- name: Set job name
run: echo JOB_NAME="$GITHUB_JOB" >> $GITHUB_ENV
- name: "Store start time"
run: echo TEST_START_TIME=$(date +%s)000 >> $GITHUB_ENV
- name: "Set environment variables"
run: |
RUNNER_NAME=$(echo "${{ runner.name }}" | grep -o 'ghrunner[0-9]\+' | sed 's/ghrunner\([0-9]\+\)/ghrunner_\1/')
echo "PYTEST_DEBUG_TEMPROOT=/var/lib/github/${RUNNER_NAME}/_temp" >> $GITHUB_ENV
echo INFRAHUB_IMAGE_VER=local-${{ runner.name }}-${{ github.sha }} >> $GITHUB_ENV
echo INFRAHUB_TESTING_IMAGE_VER=local-${{ runner.name }}-${{ github.sha }} >> $GITHUB_ENV
echo INFRAHUB_TESTING_DOCKER_IMAGE=opsmill/infrahub >> $GITHUB_ENV
echo INFRAHUB_TESTING_DOCKER_PULL=false >> $GITHUB_ENV
echo NEO4J_DOCKER_IMAGE=neo4j:2025.10.1-enterprise >> $GITHUB_ENV
- name: Build no-netlink shim
run: |
gcc -shared -fPIC -Wall -Wextra \
-o "$RUNNER_TEMP/no_netlink.so" \
tests/e2e/fixtures/no_netlink.c -ldl
echo "NO_NETLINK_SO=$RUNNER_TEMP/no_netlink.so" >> "$GITHUB_ENV"
- name: Build Demo
run: |
echo "::group::Build infrahub container"
uv run invoke dev.build
echo "::endgroup::"
- name: Run Playwright tests
if: matrix.shard != 'tutorial'
env:
INFRAHUB_TESTING_RESPONSE_DELAY: ${{ needs.files-changed.outputs.e2e_pytest_tests == 'true' && '1' || '0' }}
run: exec tini -s -g -- uv run pytest -c tests/e2e/pytest.ini tests/e2e --ignore=tests/e2e/tutorial -m shard_${{ matrix.shard }}
- name: Run tutorial Playwright tests
if: matrix.shard == 'tutorial'
run: exec tini -s -g -- uv run pytest -c tests/e2e/pytest.ini tests/e2e/tutorial
- name: playwright-report
if: always()
uses: actions/upload-artifact@v7
with:
name: E2E-testing-pytest-playwright-${{ matrix.shard }}
path: |
test-results/
playwright-junit.xml
- name: Containers after tests
if: always()
run: docker ps -a
# ------------------------------------------ E2E invoke demo ------------------------------------------------
E2E-testing-invoke-demo-start:
needs:
- prepare-environment
- frontend-lint
- files-changed
- yaml-lint
- python-lint
- infrahub-testcontainers-check
if: |
always() && !cancelled() &&
!contains(needs.*.result, 'failure') &&
!contains(needs.*.result, 'cancelled') &&
github.base_ref == 'stable' &&
needs.files-changed.outputs.e2e == 'true'
runs-on:
group: huge-runners
steps:
- name: Check out repository code
uses: actions/checkout@v7
with:
submodules: true
- name: Set up Python
id: python
uses: actions/setup-python@v7
with:
python-version: ${{ needs.prepare-environment.outputs.PYTHON_VERSION }}
- name: Install uv
uses: astral-sh/setup-uv@v7
with:
version: ${{ needs.prepare-environment.outputs.UV_VERSION }}
- name: Install dependencies
run: "uv sync --all-groups"
- name: Set job name
run: echo JOB_NAME="$GITHUB_JOB" >> $GITHUB_ENV
- name: "Set environment variables"
run: |
echo INFRAHUB_BUILD_NAME=infrahub-${{ runner.name }} >> $GITHUB_ENV
- name: "Clear docker environment"
run: docker compose -p $INFRAHUB_BUILD_NAME down -v --remove-orphans --rmi local
- name: "Store start time"
run: echo TEST_START_TIME=$(date +%s)000 >> $GITHUB_ENV
- name: Run 'invoke demo'
run: |
unset INFRAHUB_IMAGE_VER
uv run invoke demo.start demo.load-infra-schema demo.load-infra-data
- name: Display server logs
if: always()
run: docker logs "${INFRAHUB_BUILD_NAME}-server-1"
- name: Display task worker 1 logs
if: always()
run: docker logs "${INFRAHUB_BUILD_NAME}-task-worker-1"
- name: Display task worker 2 logs
if: always()
run: docker logs "${INFRAHUB_BUILD_NAME}-task-worker-2"
- name: Display task manager logs
if: always()
run: docker logs "${INFRAHUB_BUILD_NAME}-task-manager-1"
- name: Display database logs
if: always()
run: docker logs "${INFRAHUB_BUILD_NAME}-database-1"
- name: Display message-queue logs
if: always()
run: docker logs "${INFRAHUB_BUILD_NAME}-message-queue-1"
- name: "Clear docker environment and force vmagent to stop"
if: always()
run: docker compose -p $INFRAHUB_BUILD_NAME down -v --remove-orphans --rmi local
# ------------------------------------------ E2E version upgrade ------------------------------------------------
E2E-testing-version-upgrade:
needs:
- frontend-lint
- files-changed
- yaml-lint
- python-lint
- infrahub-testcontainers-check
if: |
always() && !cancelled() &&
!contains(needs.*.result, 'failure') &&
!contains(needs.*.result, 'cancelled') &&
(needs.files-changed.outputs.e2e == 'true' ||
needs.files-changed.outputs.version_upgrade_workflow == 'true')
uses: ./.github/workflows/version-upgrade.yml
# ------------------------------------------ Benchmarks ------------------------------------------------
backend-benchmark:
needs:
- prepare-environment
- frontend-lint
- files-changed
- yaml-lint
- python-lint
- infrahub-testcontainers-check
if: |
always() && !cancelled() &&
!contains(needs.*.result, 'failure') &&
!contains(needs.*.result, 'cancelled') &&
needs.files-changed.outputs.backend == 'true'
runs-on:
group: huge-runners
env:
INFRAHUB_DB_TYPE: neo4j
steps:
- name: Check out repository code
uses: actions/checkout@v7
with:
submodules: true
- name: Set up Python
id: python
uses: actions/setup-python@v7
with:
python-version: ${{ needs.prepare-environment.outputs.PYTHON_VERSION }}
- name: "Setup git credentials"
run: "git config --global user.name 'Infrahub' && \
git config --global user.email 'infrahub@opsmill.com' && \
git config --global --add safe.directory '*' && \
git config --global credential.usehttppath true && \
git config --global credential.helper '/usr/bin/env infrahub-git-credential'"
- name: Install uv
uses: astral-sh/setup-uv@v7
with:
version: ${{ needs.prepare-environment.outputs.UV_VERSION }}
- name: Install dependencies
run: "uv sync --all-groups"
- name: Update PATH
run: "echo ~/.cargo/bin >> $GITHUB_PATH"
- name: Run all benchmarks
if: contains(github.event.pull_request.labels.*.name, 'ci/run-intensive-benchmarks')
uses: CodSpeedHQ/action@v4
with:
token: ${{ secrets.CODSPEED_TOKEN }}
mode: instrumentation
run: "uv run pytest -vvv backend/tests/benchmark/ --benchmark-verbose --codspeed"
- name: Run non-intensive benchmarks
if: |
!contains(github.event.pull_request.labels.*.name, 'ci/run-intensive-benchmarks')
uses: CodSpeedHQ/action@v4
with:
token: ${{ secrets.CODSPEED_TOKEN }}
mode: instrumentation
run: "uv run pytest -vvv backend/tests/benchmark/ --benchmark-verbose --codspeed --ignore=backend/tests/benchmark/intensive"
# ------------------------------------------ Coverall Report ------------------------------------------
coverall-report:
needs:
- backend-tests-component
- backend-tests-integration
- backend-tests-unit
- frontend-tests
if: |
always() && !cancelled()
runs-on: ubuntu-latest
timeout-minutes: 10
steps:
# # NOTE: The ref value should be different when triggered by pull_request event.
# # See: https://github.com/lewagon/wait-on-check-action/issues/25.
# - name: Wait on tests (PR)
# uses: lewagon/wait-on-check-action@e106e5c43e8ca1edea6383a39a01c5ca495fd812
# if: github.event_name == 'pull_request'
# with:
# ref: ${{ github.event.pull_request.head.sha }}
# repo-token: ${{ secrets.GITHUB_TOKEN }}
# wait-interval: 10
# running-workflow-name: report
# allowed-conclusions: success,skipped,cancelled,failure
# - name: Wait on tests (push)
# if: github.event_name != 'pull_request'
# uses: lewagon/wait-on-check-action@e106e5c43e8ca1edea6383a39a01c5ca495fd812
# with:
# ref: ${{ github.sha }}
# repo-token: ${{ secrets.GITHUB_TOKEN }}
# wait-interval: 10
# running-workflow-name: report
# allowed-conclusions: success,skipped,cancelled,failure
- uses: coverallsapp/github-action@v2
continue-on-error: true
env:
COVERALLS_SERVICE_NUMBER: ${{ github.sha }}
with:
carryforward: "backend-unit,backend-integration,frontend-unit,backend-component-graphql,backend-component-core-diff,backend-component-core-schema,backend-component-other"
parallel-finished: true