name: python on: pull_request: paths: - ".github/**" - "api/**" - "api-contracts/**" - "internal/**" - "pkg/**" - "sdks/python/**" push: branches: - main paths: - "sdks/python/**" defaults: run: working-directory: ./sdks/python jobs: lint: runs-on: ubicloud-standard-4 steps: - name: Checkout code uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - name: Set up Python uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0 with: python-version: '3.14' - name: Install Poetry uses: snok/install-poetry@76e04a911780d5b312d89783f7b1cd627778900a # v1.4.1 with: version: 1.5.1 virtualenvs-create: true virtualenvs-in-project: true - name: Install linting tools run: poetry install --all-extras - name: Run Black run: poetry run black . --check --verbose --diff --color - name: Run MyPy run: poetry run mypy --config-file=pyproject.toml - name: Run Ruff run: poetry run ruff check . - name: Run Pydoclint run: poetry run pydoclint . - name: Test install run: pip install -e . test: runs-on: ubicloud-standard-4 strategy: matrix: python-version: ${{ github.event_name == 'pull_request' && fromJSON('["3.14"]') || fromJSON('["3.10", "3.11", "3.12", "3.13", "3.14"]') }} optimistic-scheduling: ["true", "false"] timeout-minutes: 20 steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - name: Install Protoc uses: arduino/setup-protoc@c65c819552d16ad3c9b72d9dfd5ba5237b9c906b # v3.0.0 with: version: "25.1" repo-token: ${{ secrets.GITHUB_TOKEN }} - name: Install Task uses: arduino/setup-task@b91d5d2c96a56797b48ac1e0e89220bf64044611 # v2.0.0 with: repo-token: ${{ secrets.GITHUB_TOKEN }} - name: Setup Go uses: actions/setup-go@4b73464bb391d4059bd26b0524d20df3927bd417 # v6.3.0 with: go-version: "1.25" - name: Start Docker dependencies working-directory: . run: docker compose up -d - name: Generate working-directory: . run: | export DATABASE_URL="postgresql://hatchet:hatchet@127.0.0.1:5431/hatchet" go run ./cmd/hatchet-migrate - name: Setup working-directory: . run: | export SEED_DEVELOPMENT=true export SERVER_PORT=8080 export SERVER_URL=http://localhost:8080 export SERVER_AUTH_COOKIE_DOMAIN=localhost export SERVER_AUTH_COOKIE_INSECURE=true export SERVER_DEFAULT_ENGINE_VERSION=V1 export SERVER_MSGQUEUE_RABBITMQ_URL="amqp://user:password@localhost:5672/" export SERVER_OPTIMISTIC_SCHEDULING_ENABLED=${{ matrix.optimistic-scheduling }} go run ./cmd/hatchet-admin quickstart go run ./cmd/hatchet-engine --config ./generated/ > engine.log 2>&1 & go run ./cmd/hatchet-api --config ./generated/ > api.log 2>&1 & sleep 30 - name: Set up Python ${{ matrix.python-version }} uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0 with: python-version: ${{ matrix.python-version }} - name: Display Python version run: python -c "import sys; print(sys.version)" - name: Install Poetry uses: snok/install-poetry@76e04a911780d5b312d89783f7b1cd627778900a # v1.4.1 with: version: 1.5.1 virtualenvs-create: true virtualenvs-in-project: true - name: Install dependencies run: poetry install --no-interaction --all-extras - name: Generate Env File working-directory: . run: | echo "HATCHET_CLIENT_TOKEN=$(go run ./cmd/hatchet-admin token create --config ./generated/ --tenant-id 707d0855-80ab-4e1f-a156-f1c4546cbf52)" >> $GITHUB_ENV echo "HATCHET_CLIENT_TLS_ROOT_CA_FILE=../../certs/ca.cert" >> $GITHUB_ENV echo "HATCHET_CLIENT_WORKER_HEALTHCHECK_ENABLED=True" >> $GITHUB_ENV - name: Set HATCHET_CLIENT_NAMESPACE run: | PYTHON_VERSION=$(python -c "import sys; print(f'py{sys.version_info.major}{sys.version_info.minor}')") SHORT_SHA=$(git rev-parse --short HEAD) echo "HATCHET_CLIENT_NAMESPACE=${PYTHON_VERSION}-${SHORT_SHA}" >> $GITHUB_ENV - name: Run pytest run: | echo "Using HATCHET_CLIENT_NAMESPACE: $HATCHET_CLIENT_NAMESPACE" poetry run pytest -s -vvv --maxfail=5 --capture=no --retries 3 --retry-delay 2 -n auto - name: Upload engine logs if: always() uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0 with: name: ${{ env.HATCHET_CLIENT_NAMESPACE }}-opt-${{ matrix.optimistic-scheduling }}-engine-logs path: engine.log - name: Upload API logs if: always() uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0 with: name: ${{ env.HATCHET_CLIENT_NAMESPACE }}-opt-${{ matrix.optimistic-scheduling }}-api-logs path: api.log publish: runs-on: ubicloud-standard-4 needs: [lint, test] if: github.ref == 'refs/heads/main' steps: - name: Checkout Repository uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: submodules: recursive - name: Set up Python uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0 with: python-version: "3.x" - name: Install Poetry run: | pipx install poetry==1.7.1 - name: Run publish.sh script run: | CURRENT_PYPI_VERSION=$(pip index versions hatchet-sdk | awk 'NR==1 {gsub(/[()]/,"",$2); print $2}') NEW_VERSION=$(cat pyproject.toml| grep "^version =" | cut -d '"' -f 2) if [ "$CURRENT_PYPI_VERSION" == "$NEW_VERSION" ]; then echo "Version has not changed. Skipping publish." exit 0 fi sh publish.sh env: POETRY_PYPI_TOKEN_PYPI: ${{ secrets.POETRY_PYPI_TOKEN_PYPI }}