Skip to content

Commit

Permalink
feat: add windows support
Browse files Browse the repository at this point in the history
  • Loading branch information
alejandrodnm committed Nov 21, 2024
1 parent 4a35fc6 commit 99d62f3
Show file tree
Hide file tree
Showing 12 changed files with 157 additions and 80 deletions.
70 changes: 70 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,76 @@ jobs:
just ext docker-stop
just ext docker-rm
build-and-test-extension-windows-pg14:
runs-on: windows-latest

steps:
- uses: actions/checkout@v4
- uses: taiki-e/install-action@just

- name: Install PostgreSQL
uses: ikalnytskyi/action-setup-postgres@v7
with:
postgres-version: 16

- name: Configure Passwordless Authentication
shell: bash
run: |
# This is the PGDATA dir used on the previous step.
PGDATA="$RUNNER_TEMP/pgdata"
# Add trust authentication to pg_hba.conf the extension tests
# required this, otherwise they will fail.
echo "host all all 127.0.0.1/32 trust" > "$PGDATA/pg_hba.conf"
echo "host all all ::1/128 trust" >> "$PGDATA/pg_hba.conf"
# Restart PostgreSQL to apply changes
pg_ctl -D "$PGDATA" restart
- name: Install pgvector
shell: cmd
env:
PGROOT: "C:/Program Files/PostgreSQL/16"
run: |
git clone --branch v0.8.0 https://github.com/pgvector/pgvector.git
cd pgvector
call "C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Auxiliary\Build\vcvars64.bat" && ^
nmake /NOLOGO /F Makefile.win && ^
nmake /NOLOGO /F Makefile.win install
- name: Create pip cache directory
run: |
New-Item -Path "C:\Users\runneradmin\AppData\Local\pip\cache" -ItemType Directory -Force
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: "3.10"
cache: "pip" # caching pip dependencies

- name: Install test dependencies
shell: cmd
run: |
pip3 install -r projects/extension/requirements-test.txt
- name: Build and install extension
shell: cmd
env:
PGAI_EXT_SKIP_BUILD_CHECKS: "true"
run: |
just ext build-install
- name: Run test server
shell: cmd
env:
PYTHONUTF8: 1
run: |
start /b python3 -m fastapi dev projects/extension/tests/vectorizer/server.py
- name: Run test
shell: cmd
run: |
just ext test
build-and-test-pgai:
runs-on: ubuntu-latest

Expand Down
115 changes: 68 additions & 47 deletions projects/extension/build.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
#!/usr/bin/env python3
import hashlib
import re
import os
import platform
import re
import shutil
import subprocess
import sys
import tempfile
from pathlib import Path


HELP = """Available targets:
- help displays this message and exits
- build-install runs build followed by install
Expand Down Expand Up @@ -325,9 +325,10 @@ def build_feature_flags() -> str:


def build_sql() -> None:
check_versions()
check_incremental_sql_files(incremental_sql_files())
check_idempotent_sql_files(idempotent_sql_files())
if not os.environ.get("PGAI_EXT_SKIP_BUILD_CHECKS", "").lower() == "true":
check_versions()
check_incremental_sql_files(incremental_sql_files())
check_idempotent_sql_files(idempotent_sql_files())
build_control_file()
hr = "".rjust(80, "-") # "horizontal rule"
osf = output_sql_file()
Expand Down Expand Up @@ -375,34 +376,51 @@ def clean_sql() -> None:


def postgres_bin_dir() -> Path:
bin_dir = os.getenv("PG_BIN")
if bin_dir:
return Path(bin_dir).resolve()
else:
bin_dir = Path(f"/usr/lib/postgresql/{pg_major()}/bin")
bin_dir_env = os.getenv("PG_BIN")
if bin_dir_env:
bin_dir = Path(bin_dir_env)
if bin_dir.is_dir():
return bin_dir.resolve()
else:
p = shutil.which("pg_config")
if not p:
fatal("pg_config not found")
return Path(p).parent.resolve()
dir = bin_dir.resolve()
print(f"pg bin dir: using PG_BIN environment variable {dir}")
return dir

bin_dir = Path(f"/usr/lib/postgresql/{pg_major()}/bin")
if platform.system() == "Windows":
program_files = os.environ.get("ProgramFiles", r"C:\Program Files")
bin_dir = Path(f"{program_files}\\PostgreSQL\\{pg_major()}\\bin")
if bin_dir.is_dir():
dir = bin_dir.resolve()
print(f"pg bin dir: using default postgres bin directory {dir}")
return dir
else:
p = shutil.which("pg_config")
if p is None:
fatal("pg_config not found")
dir = Path(p).parent.resolve()
print(f"pg bin dir: parent directory of pg_config {dir}")
return dir


def pg_config() -> Path:
return postgres_bin_dir() / "pg_config"
cmd = "pg_config"
if platform.system() == "Windows":
cmd = "pg_config.exe"
return postgres_bin_dir() / cmd


def extension_install_dir() -> Path:
proc = subprocess.run(
f"{pg_config()} --sharedir",
check=True,
shell=True,
env=os.environ,
text=True,
capture_output=True,
)
return Path(str(proc.stdout).strip()).resolve() / "extension"
try:
proc = subprocess.run(
[pg_config(), "--sharedir"],
check=True,
env=os.environ,
text=True,
capture_output=True,
)
return Path(str(proc.stdout).strip()).resolve() / "extension"
except subprocess.CalledProcessError as e:
print(f"Error running pg_config: {e.stderr}", file=sys.stderr)
raise e


def install_sql() -> None:
Expand Down Expand Up @@ -437,9 +455,12 @@ def python_install_dir() -> Path:
# don't do it. i'm warning you
# seriously.
# you'll wreck old versions. look at build_idempotent_sql_file()
return Path(
"/usr/local/lib/pgai"
).resolve() # CONTROLS WHERE THE PYTHON LIB AND DEPS ARE INSTALLED
if platform.system() == "Windows":
program_files = Path(os.environ.get("ProgramFiles", r"C:\Program Files"))
return (program_files / "pgai" / "lib").resolve()
else:
# Use the existing Unix-like directory structure
return Path("/usr/local/lib/pgai").resolve()


def install_old_py_deps() -> None:
Expand Down Expand Up @@ -468,25 +489,25 @@ def install_prior_py() -> None:
fatal(f"'{os.sep}' in version {version}. this is not supported")
version_target_dir = python_install_dir().joinpath(version)
if version_target_dir.exists():
print(f"Version {version} already installed in {version_target_dir}")
continue
tmp_dir = Path(tempfile.gettempdir()).joinpath("pgai", version)
tmp_dir.mkdir(parents=True, exist_ok=True)
branch = git_tag(version)
subprocess.run(
f"git clone https://github.com/timescale/pgai.git --branch {branch} {tmp_dir}",
shell=True,
check=True,
env=os.environ,
)
tmp_src_dir = tmp_dir.joinpath("projects", "extension").resolve()
subprocess.run(
f'pip3 install -v --compile -t "{version_target_dir}" "{tmp_src_dir}"',
check=True,
shell=True,
env=os.environ,
cwd=str(tmp_src_dir),
)
shutil.rmtree(tmp_dir)

with tempfile.TemporaryDirectory() as tmp_dir:
branch = git_tag(version)
subprocess.run(
f"git clone https://github.com/timescale/pgai.git --branch {branch} {tmp_dir}",
shell=True,
check=True,
env=os.environ,
)
tmp_src_dir = Path(tmp_dir).joinpath("projects", "extension").resolve()
subprocess.run(
f'pip3 install -v --compile -t "{version_target_dir}" "{tmp_src_dir}"',
check=True,
shell=True,
env=os.environ,
cwd=str(tmp_src_dir),
)


def build_init_py() -> None:
Expand Down
2 changes: 1 addition & 1 deletion projects/extension/justfile
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ PG_BIN := "/usr/lib/postgresql/" + PG_MAJOR + "/bin"

# Show list of recipes
default:
@just --list
@just --list

ci: docker-build docker-run
#!/usr/bin/env bash
Expand Down
2 changes: 2 additions & 0 deletions projects/extension/tests/vectorizer/db.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
def db_url(user: str) -> str:
return f"postgres://{user}@127.0.0.1:5432/test"
6 changes: 2 additions & 4 deletions projects/extension/tests/vectorizer/test_chunking.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,14 @@
import psycopg
import pytest

from .db import db_url

# skip tests in this module if disabled
enable_vectorizer_tests = os.getenv("ENABLE_VECTORIZER_TESTS")
if enable_vectorizer_tests == "0":
pytest.skip(allow_module_level=True)


def db_url(user: str) -> str:
return f"postgres://{user}@127.0.0.1:5432/test"


def test_chunking_character_text_splitter():
tests = [
(
Expand Down
5 changes: 1 addition & 4 deletions projects/extension/tests/vectorizer/test_embedding.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,14 @@

import psycopg
import pytest
from .db import db_url

# skip tests in this module if disabled
enable_vectorizer_tests = os.getenv("ENABLE_VECTORIZER_TESTS")
if enable_vectorizer_tests == "0":
pytest.skip(allow_module_level=True)


def db_url(user: str) -> str:
return f"postgres://{user}@127.0.0.1:5432/test"


def test_embedding_openai():
tests = [
(
Expand Down
6 changes: 2 additions & 4 deletions projects/extension/tests/vectorizer/test_formatting.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,14 @@
import psycopg
import pytest

from .db import db_url

# skip tests in this module if disabled
enable_vectorizer_tests = os.getenv("ENABLE_VECTORIZER_TESTS")
if enable_vectorizer_tests == "0":
pytest.skip(allow_module_level=True)


def db_url(user: str) -> str:
return f"postgres://{user}@127.0.0.1:5432/test"


def test_formatting_python_template():
tests = [
(
Expand Down
6 changes: 2 additions & 4 deletions projects/extension/tests/vectorizer/test_grants.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,14 @@
import psycopg
import pytest

from .db import db_url

# skip tests in this module if disabled
enable_vectorizer_tests = os.getenv("ENABLE_VECTORIZER_TESTS")
if enable_vectorizer_tests == "0":
pytest.skip(allow_module_level=True)


def db_url(user: str) -> str:
return f"postgres://{user}@127.0.0.1:5432/test"


def test_grant_to():
tests = [
(
Expand Down
7 changes: 3 additions & 4 deletions projects/extension/tests/vectorizer/test_indexing.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,15 @@
import psycopg
import pytest


from .db import db_url

# skip tests in this module if disabled
enable_vectorizer_tests = os.getenv("ENABLE_VECTORIZER_TESTS")
if enable_vectorizer_tests == "0":
pytest.skip(allow_module_level=True)


def db_url(user: str) -> str:
return f"postgres://{user}@127.0.0.1:5432/test"


def test_indexing_none():
tests = [
(
Expand Down
6 changes: 2 additions & 4 deletions projects/extension/tests/vectorizer/test_processing.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,14 @@
import psycopg
import pytest

from .db import db_url

# skip tests in this module if disabled
enable_vectorizer_tests = os.getenv("ENABLE_VECTORIZER_TESTS")
if enable_vectorizer_tests == "0":
pytest.skip(allow_module_level=True)


def db_url(user: str) -> str:
return f"postgres://{user}@127.0.0.1:5432/test"


def test_processing_default():
tests = [
(
Expand Down
6 changes: 2 additions & 4 deletions projects/extension/tests/vectorizer/test_scheduling.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,14 @@
import psycopg
import pytest

from .db import db_url

# skip tests in this module if disabled
enable_vectorizer_tests = os.getenv("ENABLE_VECTORIZER_TESTS")
if enable_vectorizer_tests == "0":
pytest.skip(allow_module_level=True)


def db_url(user: str) -> str:
return f"postgres://{user}@127.0.0.1:5432/test"


def test_scheduling_none():
tests = [
(
Expand Down
Loading

0 comments on commit 99d62f3

Please sign in to comment.