Ai 1473 server transport tracking #2564
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
name: CI | |
# How the CI Pipeline Works | |
# - The CI workflow runs on all push events and pull requests. | |
# - For pull requests from forks (coming from a different repository), we skip jobs/actions that need secrets (e.g., | |
# publishing results, integration tests) to avoid exposing them. Only safe checks like local tests and flake8 are run. | |
# - For pull requests from branches in this repository, the workflow is skipped to avoid running it twice (once for the | |
# push and once for the PR). | |
# - The full workflow (including jobs requiring secrets) runs only on pushes events to branches in this repository | |
on: [ push, pull_request ] | |
concurrency: ci-${{ github.ref }} | |
permissions: | |
contents: read | |
checks: write | |
jobs: | |
build: | |
name: Build, test and package | |
# run this job only for push (avoiding pull requests from the same repo) or for pull requests from different repo | |
if: github.event_name == 'push' || github.event.pull_request.head.repo.full_name != github.repository | |
runs-on: ubuntu-latest | |
strategy: | |
matrix: | |
python-version: ["3.10", "3.11", "3.12"] | |
outputs: | |
is_semantic_tag: ${{ steps.get_package_version.outputs.is_semantic_tag }} | |
tag: ${{ steps.get_package_version.outputs.tag }} | |
version: ${{ steps.get_package_version.outputs.version }} | |
wheel_artifact_id: ${{ steps.wheel_artifact_upload.outputs.artifact-id }} | |
steps: | |
- uses: actions/checkout@v4 | |
- name: Set up Python ${{ matrix.python-version }} | |
uses: actions/setup-python@v5 | |
with: | |
python-version: ${{ matrix.python-version }} | |
- name: Install dependencies | |
run: | | |
python -m pip install --upgrade pip | |
pip install uv | |
uv sync --frozen --no-editable --extra dev | |
# Runs tests with coverage and generates coverage.xml file and test-results.xml file | |
# and checks flake8 code-style formatting that is compatible with isort & black | |
# and verifies TOOLS.md is up-to-date with tool definitions | |
# see setup in pyproject.toml | |
- name: Unit tests, code style and documentation check | |
run: | | |
uv run tox | |
- name: Publish test results | |
uses: dorny/test-reporter@v1 | |
# run this step even if a previous step failed, but only for push events or pull requests from the same repo | |
if: (success() || failure()) && (github.event_name == 'push' || github.event.pull_request.head.repo.full_name == github.repository) | |
with: | |
name: Test results (${{ matrix.python-version }}) | |
path: ./test-results.xml | |
reporter: 'java-junit' | |
- name: Upload coverage to Codecov | |
# run this step only for push events or pull requests from the same repo | |
if: github.event_name == 'push' || github.event.pull_request.head.repo.full_name == github.repository | |
uses: codecov/codecov-action@v4 | |
with: | |
file: ./coverage.xml | |
fail_ci_if_error: true | |
token: ${{ secrets.CODECOV_TOKEN }} | |
- name: Build wheels package | |
run: | | |
uv build --wheel --no-sources | |
- name: Get package version | |
id: get_package_version | |
if: matrix.python-version == '3.10' | |
run: | | |
VERSION=`uv run python3 -c 'import importlib.metadata; print(importlib.metadata.version("keboola_mcp_server"))'` | |
TAG="${GITHUB_REF##*/}" | |
IS_SEMANTIC_TAG=$(echo "$TAG" | grep -q '^v\?[0-9]\+\.[0-9]\+\.[0-9]\+$' && echo true || echo false) | |
echo "Version = '$VERSION', Tag = '$TAG', is semantic tag = '$IS_SEMANTIC_TAG'" | |
echo "is_semantic_tag=$IS_SEMANTIC_TAG" >> $GITHUB_OUTPUT | |
echo "tag=$TAG" >> $GITHUB_OUTPUT | |
echo "version=${VERSION}" >> $GITHUB_OUTPUT | |
- name: Upload wheel package | |
id: wheel_artifact_upload | |
# run this step only for push events or pull requests from the same repo | |
if: matrix.python-version == '3.10' && (github.event_name == 'push' || github.event.pull_request.head.repo.full_name == github.repository) | |
uses: actions/upload-artifact@v4 | |
with: | |
name: keboola_mcp_server-${{ steps.get_package_version.outputs.version }}-py3-none-any.whl | |
path: dist/keboola_mcp_server-${{ steps.get_package_version.outputs.version }}-py3-none-any.whl | |
if-no-files-found: error | |
compression-level: 0 # wheels are ZIP archives | |
retention-days: 7 | |
integration_tests: | |
name: Integration Tests | |
needs: build | |
# run this job only for push events (not pull requests) | |
if: github.event_name == 'push' | |
runs-on: ubuntu-latest | |
strategy: | |
matrix: | |
python-version: ["3.10", "3.11", "3.12"] | |
# This ensures tests run sequentially, not in parallel | |
max-parallel: 1 | |
steps: | |
- uses: actions/checkout@v4 | |
- name: Set up Python ${{ matrix.python-version }} | |
uses: actions/setup-python@v5 | |
with: | |
python-version: ${{ matrix.python-version }} | |
- name: Install dependencies | |
run: | | |
python -m pip install --upgrade pip | |
pip install uv | |
uv sync --frozen --no-editable --extra dev | |
- name: Integration tests | |
# run actual tests only for pushes to the same repository (not forks) | |
if: github.repository == github.event.repository.full_name | |
env: | |
INTEGTEST_STORAGE_TOKEN: ${{ secrets.INTEGTEST_STORAGE_TOKEN }} | |
INTEGTEST_STORAGE_API_URL: ${{ vars.INTEGTEST_STORAGE_API_URL }} | |
INTEGTEST_WORKSPACE_SCHEMA: ${{ vars.INTEGTEST_WORKSPACE_SCHEMA }} | |
run: | | |
uv run tox -e integtests | |
- name: Skip integration tests for forks | |
# show a message when tests are skipped for forks | |
if: github.repository != github.event.repository.full_name | |
run: | | |
echo "Integration tests skipped for fork repository" | |
echo "Dependencies installed successfully - setup is working correctly" | |
- name: Publish integration test results | |
uses: dorny/test-reporter@v1 | |
# publish results only when actual tests were run (same repository) | |
if: (always()) && github.repository == github.event.repository.full_name | |
with: | |
name: Integration test results (${{ matrix.python-version }}) | |
path: ./integtest-results.xml | |
reporter: 'java-junit' | |
build_docker_image_and_do_basic_test: | |
name: Build Docker image and do basic test | |
needs: | |
- build | |
- integration_tests | |
runs-on: ubuntu-latest | |
# run this job only for push events (not pull requests) | |
if: github.event_name == 'push' | |
steps: | |
- uses: actions/checkout@v4 | |
- name: Set up Docker Buildx | |
uses: docker/setup-buildx-action@v3 | |
- name: Docker login | |
uses: docker/login-action@v3 | |
with: | |
username: ${{ secrets.DOCKERHUB_PUSH_USER }} | |
password: ${{ secrets.DOCKERHUB_PUSH_TOKEN }} | |
- name: Build Docker image | |
uses: docker/build-push-action@v6 | |
with: | |
context: . | |
file: ./Dockerfile | |
platforms: linux/amd64 | |
tags: "keboola/mcp-server:ci" | |
push: false | |
load: true | |
cache-from: type=gha | |
cache-to: type=gha,mode=max | |
- name: Run simple e2e test | |
run: | | |
STORAGE_API_TOKEN=${{ secrets.INTEGTEST_STORAGE_TOKEN }} STORAGE_API_URL=${{ vars.INTEGTEST_STORAGE_API_URL }} ./tests/docker/ci.sh | |
deploy_to_pypi: | |
needs: | |
- build | |
- integration_tests | |
runs-on: ubuntu-latest | |
if: | | |
startsWith(github.ref, 'refs/tags/') && | |
needs.build.outputs.is_semantic_tag == 'true' && | |
needs.build.outputs.tag == format('v{0}', needs.build.outputs.version) | |
steps: | |
- name: Download wheel package | |
uses: actions/download-artifact@v4 | |
with: | |
name: keboola_mcp_server-${{ needs.build.outputs.version }}-py3-none-any.whl | |
path: dist/ | |
- name: Publish package | |
uses: pypa/gh-action-pypi-publish@27b31702a0e7fc50959f5ad993c78deac1bdfc29 | |
with: | |
user: __token__ | |
password: ${{ secrets.PYPI_API_TOKEN }} |