diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml deleted file mode 100644 index 88a9f8bc7..000000000 --- a/.github/workflows/lint.yml +++ /dev/null @@ -1,27 +0,0 @@ -name: Lint -on: - push: - pull_request: -concurrency: - group: ${{ github.head_ref || github.sha }}-${{ github.workflow }} - cancel-in-progress: true -jobs: - pre-commit: - name: pre-commit - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v6 - - name: Setup Python - uses: actions/setup-python@v6 - - name: Install pre-commit - run: | - python3 -m pip install pre-commit - pre-commit run --show-diff-on-failure --color=always - - name: Cache pre-commit - uses: actions/cache@v5 - with: - path: ~/.cache/pre-commit - key: pre-commit-${{ hashFiles('.pre-commit-config.yaml') }} - - name: Run pre-commit - run: | - pre-commit run --all-files --color=always --show-diff-on-failure diff --git a/.github/workflows/linux.yml b/.github/workflows/linux.yml deleted file mode 100644 index 252cd4a5c..000000000 --- a/.github/workflows/linux.yml +++ /dev/null @@ -1,193 +0,0 @@ -name: Linux -on: - push: - pull_request: - schedule: - # * UTC 16:30 - # * JST 01:30 - - cron: | - 30 16 * * * -concurrency: - group: ${{ github.head_ref || github.sha }}-${{ github.workflow }} - cancel-in-progress: true -jobs: - test: - if: >- - github.event_name != 'schedule' || - (github.event_name == 'schedule' && - github.repository_owner == 'pgroonga') - name: Test - timeout-minutes: ${{ github.event_name == 'schedule' && 150 || 30 }} - strategy: - fail-fast: false - matrix: - label: - - PostgreSQL 14 - - PostgreSQL 15 - - PostgreSQL 16 - - PostgreSQL 17 - - PostgreSQL 18 - - PostgreSQL 18 with Groonga main - - PostgreSQL 19 - include: - - label: PostgreSQL 14 - postgresql-version: "14" - - label: PostgreSQL 15 - postgresql-version: "15" - - label: PostgreSQL 16 - postgresql-version: "16" - - label: PostgreSQL 17 - postgresql-version: "17" - - label: PostgreSQL 18 - postgresql-version: "18" - - label: PostgreSQL 18 with Groonga main - groonga-main: "yes" - postgresql-version: "18" - - label: PostgreSQL 19 - postgresql-unreleased: "yes" - postgresql-version: "19" - env: - GROONGA_MAIN: ${{ matrix.groonga-main }} - POSTGRESQL_UNRELEASED: ${{ matrix.postgresql-unreleased }} - PGROONGA_BENCHMARK_GEMFILE: ${{ github.workspace }}/pgroonga-benchmark/Gemfile - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v6 - with: - submodules: recursive - - uses: actions/checkout@v6 - with: - repository: pgroonga/benchmark - path: pgroonga-benchmark - - name: Prepare language model caching - if: matrix.groonga-main == 'yes' - run: | - download_cache_dir="/tmp/cache/language-models" - mkdir -p "${download_cache_dir}" - echo "GRN_LANGUAGE_MODEL_DOWNLOAD_CACHE_DIR=${download_cache_dir}" >> ${GITHUB_ENV} - echo "PGRN_LANGUAGE_MODEL_TEST=yes" >> ${GITHUB_ENV} - - name: Cache language models - if: matrix.groonga-main == 'yes' - uses: actions/cache@v5 - with: - path: /tmp/cache/language-models - key: linux-test-cache-language-models-${{ hashFiles('sql/function/language-model-vectorize/**') }} - restore-keys: linux-test-cache-language-models- - - name: Install dependency - run: | - curl \ - --silent \ - --location \ - https://github.com/groonga/groonga/raw/HEAD/data/travis/setup.sh | \ - sh - if [ "${GROONGA_MAIN}" != "yes" ]; then - sudo apt -y -V install \ - groonga-token-filter-stem \ - groonga-tokenizer-mecab \ - libmsgpack-dev - fi - sudo apt -y -V install \ - libmecab-dev \ - libxxhash-dev - - name: Install PostgreSQL - run: | - sudo apt -y -V purge '^postgresql' - suite=$(lsb_release -cs)-pgdg - sudo tee /etc/apt/sources.list.d/pgdg.list <- - github.event_name != 'schedule' || - (github.event_name == 'schedule' && - github.repository_owner == 'pgroonga') - name: Test - timeout-minutes: 30 - strategy: - fail-fast: false - matrix: - postgresql-version: - - "14" - - "15" - - "16" - - "17" - - "18" - env: - PGROONGA_BENCHMARK_GEMFILE: ${{ github.workspace }}/pgroonga-benchmark/Gemfile - runs-on: macos-latest - steps: - - uses: actions/checkout@v6 - with: - submodules: recursive - - uses: actions/checkout@v6 - with: - repository: pgroonga/benchmark - path: pgroonga-benchmark - - name: Update Homebrew if needed - run: | - set -x - required_groonga_version=$(grep "^REQUIRED_GROONGA_VERSION" makefiles/pgrn-pgxs.mk | cut -d' ' -f 3) - homebrew_groonga_version=$(brew info --json groonga | jq -r '.[0].versions.stable') - older_groonga_version=$( \ - (echo ${required_groonga_version}; \ - echo ${homebrew_groonga_version}) | \ - sort --version-sort | \ - head -n1 \ - ) - if ([ "${older_groonga_version}" = "${homebrew_groonga_version}" ] && \ - [ "${homebrew_groonga_version}" != "${required_groonga_version}" ]) || \ - ! brew info postgresql@${{ matrix.postgresql-version }}; then - brew update - # Force overwriting Python related symbolic links because - # Python related files in $(brew --prefix)/bin/ are provided - # system Python that is pre-installed on GitHub Actions - # runner. - brew install --overwrite python@3.12 python@3.11 python@3.10 - fi - - name: Install dependency - run: | - sed \ - -i '' \ - -e 's/postgresql/postgresql@${{ matrix.postgresql-version }}/g' \ - Brewfile - brew bundle - - name: Update maxfiles limit - # To avoid the error `system call error: Too many open files`. - run: sudo launchctl limit maxfiles unlimited unlimited - - name: Prepare PostgreSQL - run: | - cat <> $(brew --prefix)/var/postgresql@${{ matrix.postgresql-version }}/postgresql.conf - enable_partitionwise_join = on - max_prepared_transactions = 1 - random_page_cost = 0 - CONF - brew services start postgresql@${{ matrix.postgresql-version }} - echo $(brew --prefix postgresql@${{ matrix.postgresql-version }})/bin >> \ - ${GITHUB_PATH} - - name: Configure PGroonga - run: | - meson setup \ - --buildtype=debug \ - -Dpg_config=$(brew --prefix postgresql@${{ matrix.postgresql-version }})/bin/pg_config \ - ../pgroonga.build - - name: Build PGroonga - run: | - meson compile -C ../pgroonga.build - - name: Install PGroonga - run: | - meson install -C ../pgroonga.build - - name: Run regression test - run: | - # TODO: Remove me when groonga formula enables libstemmer - rm sql/full-text-search/text/options/token-filters/custom.sql - meson test -C ../pgroonga.build -v - - name: Show diff - if: failure() - run: | - cat ../pgroonga.build/regression.diffs - - name: Show pgroonga.log - if: failure() - run: | - cat \ - $(brew --prefix)/var/postgresql@${{ matrix.postgresql-version }}/pgroonga.log - - uses: ruby/setup-ruby@v1 - with: - ruby-version: ruby - bundler-cache: true - cache-version: ${{ matrix.postgresql-version }} - - uses: actions/cache@v5 - with: - path: | - ~/Library/Caches/red-datasets - key: red-datasets-macos - - name: Run unit test - run: | - PATH="$(brew --prefix postgresql@${{ matrix.postgresql-version }})/bin:$PATH" \ - bundle exec ruby \ - -I${{ github.workspace }}/pgroonga-benchmark/lib \ - test/run-test.rb \ - --ignore-testcase=/CrashSafer/ \ - --ignore-testcase=/StreamingReplication/ \ - --verbose diff --git a/.github/workflows/package.yml b/.github/workflows/package.yml deleted file mode 100644 index f289979a0..000000000 --- a/.github/workflows/package.yml +++ /dev/null @@ -1,271 +0,0 @@ -name: Package -on: - push: - pull_request: - schedule: - - cron: | - 0 0 * * * -concurrency: - group: ${{ github.head_ref || github.sha }}-${{ github.workflow }} - cancel-in-progress: true -jobs: - source: - if: >- - github.event_name != 'schedule' || - (github.event_name == 'schedule' && - github.repository_owner == 'pgroonga') - name: Source - timeout-minutes: 5 - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v6 - with: - submodules: recursive - - uses: ruby/setup-ruby@v1 - with: - ruby-version: ruby - bundler-cache: true - - name: Build archive - run: | - bundle exec rake dist - - name: Generate chechsum - run: | - version="$(bundle exec rake version)" - for sha in sha256 sha512; do - ${sha}sum pgroonga-${version}.tar.gz > pgroonga-${version}.tar.gz.${sha} - ${sha}sum pgroonga-${version}.zip > pgroonga-${version}.zip.${sha} - done - - # Artifact - - uses: actions/upload-artifact@v6 - with: - name: release-source - path: | - pgroonga-*.tar.gz* - pgroonga-*.zip* - - linux: - name: Linux - needs: source - timeout-minutes: 15 - strategy: - fail-fast: false - matrix: - package-id: - - postgresql-18-pgdg-pgroonga-debian-bookworm - - postgresql-18-pgdg-pgroonga-debian-bookworm-arm64 - - postgresql-18-pgdg-pgroonga-debian-trixie - - postgresql-18-pgdg-pgroonga-debian-trixie-arm64 - - postgresql-18-pgdg-pgroonga-ubuntu-jammy - - postgresql-18-pgdg-pgroonga-ubuntu-jammy-arm64 - - postgresql-18-pgdg-pgroonga-ubuntu-noble - - postgresql-18-pgdg-pgroonga-ubuntu-noble-arm64 - - postgresql-18-pgdg-pgroonga-almalinux-8 - - postgresql-18-pgdg-pgroonga-almalinux-9 - - postgresql-18-pgdg-pgroonga-almalinux-10 - - postgresql-17-pgdg-pgroonga-debian-bookworm - - postgresql-17-pgdg-pgroonga-debian-bookworm-arm64 - - postgresql-17-pgdg-pgroonga-debian-trixie - - postgresql-17-pgdg-pgroonga-debian-trixie-arm64 - - postgresql-17-pgdg-pgroonga-ubuntu-jammy - - postgresql-17-pgdg-pgroonga-ubuntu-jammy-arm64 - - postgresql-17-pgdg-pgroonga-ubuntu-noble - - postgresql-17-pgdg-pgroonga-ubuntu-noble-arm64 - - postgresql-17-pgdg-pgroonga-almalinux-8 - - postgresql-17-pgdg-pgroonga-almalinux-9 - - postgresql-17-pgdg-pgroonga-almalinux-10 - - postgresql-17-pgroonga-debian-trixie - - postgresql-17-pgroonga-debian-trixie-arm64 - - postgresql-16-pgdg-pgroonga-debian-bookworm - - postgresql-16-pgdg-pgroonga-debian-bookworm-arm64 - - postgresql-16-pgdg-pgroonga-debian-trixie - - postgresql-16-pgdg-pgroonga-debian-trixie-arm64 - - postgresql-16-pgdg-pgroonga-ubuntu-jammy - - postgresql-16-pgdg-pgroonga-ubuntu-jammy-arm64 - - postgresql-16-pgdg-pgroonga-ubuntu-noble - - postgresql-16-pgdg-pgroonga-ubuntu-noble-arm64 - - postgresql-16-pgdg-pgroonga-almalinux-8 - - postgresql-16-pgdg-pgroonga-almalinux-9 - - postgresql-16-pgdg-pgroonga-almalinux-10 - - postgresql-16-pgroonga-ubuntu-noble - - postgresql-15-pgdg-pgroonga-debian-bookworm - - postgresql-15-pgdg-pgroonga-debian-bookworm-arm64 - - postgresql-15-pgdg-pgroonga-debian-trixie - - postgresql-15-pgdg-pgroonga-debian-trixie-arm64 - - postgresql-15-pgdg-pgroonga-ubuntu-jammy - - postgresql-15-pgdg-pgroonga-ubuntu-jammy-arm64 - - postgresql-15-pgdg-pgroonga-ubuntu-noble - - postgresql-15-pgdg-pgroonga-ubuntu-noble-arm64 - - postgresql-15-pgdg-pgroonga-almalinux-8 - - postgresql-15-pgdg-pgroonga-almalinux-9 - - postgresql-15-pgdg-pgroonga-almalinux-10 - - postgresql-15-pgroonga-debian-bookworm - - postgresql-15-pgroonga-debian-bookworm-arm64 - - postgresql-14-pgdg-pgroonga-debian-bookworm - - postgresql-14-pgdg-pgroonga-debian-bookworm-arm64 - - postgresql-14-pgdg-pgroonga-debian-trixie - - postgresql-14-pgdg-pgroonga-debian-trixie-arm64 - - postgresql-14-pgdg-pgroonga-ubuntu-jammy - - postgresql-14-pgdg-pgroonga-ubuntu-jammy-arm64 - - postgresql-14-pgdg-pgroonga-ubuntu-noble - - postgresql-14-pgdg-pgroonga-ubuntu-noble-arm64 - - postgresql-14-pgdg-pgroonga-almalinux-8 - - postgresql-14-pgdg-pgroonga-almalinux-9 - - postgresql-14-pgdg-pgroonga-almalinux-10 - - postgresql-14-pgroonga-ubuntu-jammy - # Groonga 11.0.5 or later is required - # - pgroonga-fedora-33 - env: - APACHE_ARROW_REPOSITORY: ${{ github.workspace }}/apache-arrow - # condition && true-case || false-case - # == - # condition ? true-case : false-case - runs-on: >- - ${{ (contains(matrix.package-id, 'arm64') || - contains(matrix.package-id, 'aarch64')) && 'ubuntu-24.04-arm' || - 'ubuntu-latest' }} - steps: - - uses: actions/checkout@v6 - with: - submodules: recursive - - uses: actions/checkout@v6 - with: - path: apache-arrow - repository: apache/arrow - - uses: ruby/setup-ruby@v1 - with: - ruby-version: ruby - bundler-cache: true - - name: Clone dependencies - run: | - cd .. - git clone --depth 1 https://github.com/groonga/groonga.git - cd groonga - git submodule update --init --force --recursive --depth 1 - - name: Download archive - uses: actions/download-artifact@v7 - with: - name: release-source - - name: Configure - run: | - set -eux - package=$(echo ${{ matrix.package-id }} | \ - sed -E -e 's/-(debian|ubuntu|almalinux|fedora).*$//g') - os=$(echo ${{ matrix.package-id }} | \ - sed -E -e 's/^.*-((debian|ubuntu|almalinux|fedora).*)$/\1/g') - echo "PACKAGE=${package}" >> ${GITHUB_ENV} - echo "OS=${os}" >> ${GITHUB_ENV} - case ${os} in - debian-*|ubuntu-*) - echo "PACKAGE_TYPE=apt" >> ${GITHUB_ENV} - ;; - almalinux-*|fedora-*) - echo "PACKAGE_TYPE=yum" >> ${GITHUB_ENV} - ;; - esac - test_incus_image=$(echo ${os} | sed -E -e 's/-/\//g') - echo "TEST_INCUS_IMAGE=images:${test_incus_image}" >> ${GITHUB_ENV} - - name: Cache ccache - uses: actions/cache@v5 - with: - path: packages/${{ env.PACKAGE }}/${{ env.PACKAGE_TYPE }}/build/ccache - key: package-${{ matrix.package-id }}-ccache-${{ hashFiles('src/*.c', 'src/*.h') }} - restore-keys: package-${{ matrix.package-id }}-ccache- - - name: Build with Docker - env: - GH_TOKEN: ${{ github.token }} - GROONGA_REPOSITORY: ../../../groonga - run: | - set -x - cd packages/${PACKAGE} - rake version:update - rake \ - ${PACKAGE_TYPE}:build \ - $(echo ${PACKAGE_TYPE} | tr 'a-z' 'A-Z')_TARGETS=${OS} \ - BUILD_DIR=build - mv ${PACKAGE_TYPE}/repositories/ ../../ - - # Artifact - - uses: actions/upload-artifact@v6 - with: - name: packages-${{ matrix.package-id }} - path: repositories/ - - # Test - - name: Install Incus - run: | - sudo apt update - sudo apt install -y -V incus - - name: Allow egress network traffic flows for Incus - run: | - sudo iptables -I DOCKER-USER -i incusbr0 -j ACCEPT - sudo iptables -I DOCKER-USER -o incusbr0 -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT - - name: Prepare container - run: | - set -x - sudo incus admin init --auto - sudo incus launch --quiet ${{ env.TEST_INCUS_IMAGE }} target - mkdir -m 777 "${PWD}/host-rw" - sudo incus config device add target host-rw disk source=$PWD/host-rw path=/host-rw - sudo incus config device add target host disk source=$PWD path=/host readonly=true - # Ideally, we would use systemctl is-system-running --wait to ensure all services are fully operational. - # However, this option doesn't work in AlmaLinux 8 and results in an error. - # As a workaround, we introduced a 10-second sleep delay to allow network services time to stabilize, - # preventing DNS resolution errors when attempting to dnf install command. - # ref: https://discuss.linuxcontainers.org/t/network-issue-with-almalinux-8-9-on-github-actions-using-incus/20046 - sleep 10 - - name: Test - run: | - sudo incus exec target \ - -- \ - /host/packages/${PACKAGE_TYPE}/test.sh - - name: Delete container - run: | - sudo incus stop target - sudo incus delete target - - # Upload logs - - uses: actions/upload-artifact@v6 - if: | - failure() - with: - name: ${{ matrix.package-id }}-logs - path: host-rw/logs/ - - prepare-release: - name: Prepare for release - needs: linux - runs-on: ubuntu-latest - timeout-minutes: 5 - steps: - - uses: actions/download-artifact@v7 - with: - path: packages - pattern: packages-* - - name: Group by distribution and version - run: | - set -x - for packages_path in packages/packages-*; do - # packages/packages-postgresql-17-pgdg-pgroonga-debian-bookworm -> - # debian-bookworm - os=$(echo ${packages_path} | \ - grep -E -o '(almalinux|debian|ubuntu)-[^-]+') - - mkdir -p release/${os}/ - # packages/packages-postgresql-17-pgdg-pgroonga-debian-bookworm/debian/pool/bookworm/ -> - # release/debian-bookworm/debian/pool/bookworm/ - rsync -a ${packages_path}/ release/${os}/ - done - for release_os_path in release/*; do - # release/debian-bookworm -> - # debian-bookworm - os=$(basename ${release_os_path}) - - # release/debian-bookworm/debian/pool/bookworm/ -> - # debian-bookworm/debian/pool/bookworm/ - tar czf ${os}.tar.gz -C $(dirname ${release_os_path}) ${os} - done - - uses: actions/upload-artifact@v6 - with: - name: release-linux-packages - path: "*.tar.gz" diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml deleted file mode 100644 index 2c42343a8..000000000 --- a/.github/workflows/release.yml +++ /dev/null @@ -1,87 +0,0 @@ -name: Release -on: - push: - tags: - - "*" - pull_request: - paths: - - ".github/workflows/release.yml" -jobs: - github: - name: GitHub - runs-on: ubuntu-latest - timeout-minutes: 60 - steps: - - uses: actions/checkout@v6 - with: - fetch-depth: 0 - - uses: actions/checkout@v6 - with: - repository: "pgroonga/pgroonga.github.io" - path: "pgroonga.github.io" - - name: Download artifacts - if: | - github.ref_type == 'tag' - run: | - workflows=(package.yml windows.yml) - for workflow in "${workflows[@]}"; do - run_id="" - while true; do - echo "Waiting for run to start ${workflow}..." - run_id=$(gh run list \ - --branch ${GITHUB_REF_NAME} \ - --jq '.[].databaseId' \ - --json databaseId \ - --limit 1 \ - --workflow ${workflow}) - if [ -n "${run_id}" ]; then - break - fi - sleep 300 - done - gh run watch \ - --exit-status \ - --interval 300 \ - ${run_id} - gh run download ${run_id} \ - --dir release-artifacts \ - --pattern "release-*" - done - env: - GH_TOKEN: ${{ github.token }} - - name: Extract release note - env: - GH_TOKEN: ${{ github.token }} - run: | - ruby \ - -e 'print("## PGroonga "); \ - puts(ARGF.read.split(/^## /)[1]. \ - gsub(/ {.+?}/, ""). \ - gsub(/\[(.+?)\]\[.+?\]/) {$1})' \ - pgroonga.github.io/news/index.md | tee release-note.md - - previous_tag=$(gh release list \ - --jq '.[].tagName' \ - --json tagName \ - --limit 1) - - echo "### Contributors" | tee -a release-note.md - echo | tee -a release-note.md - command_line="git shortlog -sn ${previous_tag}.." - echo '```console' | tee -a release-note.md - echo "\$ ${command_line}" | tee -a release-note.md - ${command_line} | tee -a release-note.md - echo '```' | tee -a release-note.md - - name: Publish - if: | - github.ref_type == 'tag' - run: | - title=$(head -n1 release-note.md | sed -e 's/^## //') - tail -n +2 release-note.md > release-note-without-version.md - gh release create ${GITHUB_REF_NAME} \ - --discussion-category Releases \ - --notes-file release-note-without-version.md \ - --title "${title}" \ - release-artifacts/*/* - env: - GH_TOKEN: ${{ github.token }} diff --git a/.github/workflows/setup.yml b/.github/workflows/setup.yml deleted file mode 100644 index d118b645c..000000000 --- a/.github/workflows/setup.yml +++ /dev/null @@ -1,65 +0,0 @@ -name: Setup -on: - push: - pull_request: -concurrency: - group: ${{ github.head_ref || github.sha }}-${{ github.workflow }} - cancel-in-progress: true -jobs: - test: - name: Test - runs-on: ubuntu-latest - strategy: - fail-fast: false - matrix: - image: - - "images:debian/12" - - "images:ubuntu/22.04" - - "images:ubuntu/24.04" - steps: - - uses: actions/checkout@v6 - with: - submodules: recursive - - uses: actions/checkout@v6 - with: - path: "groonga" - repository: "groonga/groonga" - submodules: recursive - - name: Install Incus - run: | - # We can use the official Ubuntu APT repository when - # ubuntu-latest is Ubuntu 24.04. - sudo curl -fsSL https://pkgs.zabbly.com/key.asc -o /etc/apt/keyrings/zabbly.asc - cat <= 17 }} + run: | + # pg_regress.exe depends on libpq.dll and libpq.dll exists + # in pgsql\bin\. We need to set PATH or use same directory + # to resolve the dependency. We use the same directory approach. + # This must run BEFORE meson setup so find_program() finds the working copy. + Copy-Item ` + -Path ..\pgsql\lib\pgxs\src\test\regress\pg_regress.exe ` + -Destination ..\pgsql\bin\ + - name: Configure PGroonga + shell: cmd + run: | + call "%VC_PREFIX%\Auxiliary\Build\vcvars64.bat" + for %%I in (%CD%\..) do set "PARENT_DIR=%%~fI" + for %%I in (%CD%) do set "SOURCE_DIR=%%~fI" + set PKG_CONFIG_PATH=%SOURCE_DIR%\vendor\groonga.install\lib\pkgconfig + meson setup ^ + --wipe ^ + ..\pgroonga.build ^ + --prefix="%PARENT_DIR%\pgsql" ^ + -Dpg_config="%PARENT_DIR%\pgsql\bin\pg_config.exe" + - name: Build PGroonga + shell: cmd + run: | + call "%VC_PREFIX%\Auxiliary\Build\vcvars64.bat" + meson compile -C ..\pgroonga.build + - name: Install PGroonga + shell: cmd + run: | + call "%VC_PREFIX%\Auxiliary\Build\vcvars64.bat" + meson install -C ..\pgroonga.build # Upload artifacts - name: Package run: | New-Item artifacts -ItemType Directory - cmake ` - --build ..\build ` - --target package ` - --verbose - Copy-Item -Path ..\build\*.zip -Destination artifacts + Compress-Archive -Path ..\pgsql\* -DestinationPath artifacts\pgroonga-${{ matrix.postgresql-version-major }}-windows-x64.zip Write-Output "ARTIFACT_BASENAME=$((Get-Item artifacts\*.zip).name)" | ` Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append - uses: actions/upload-artifact@v6 @@ -168,49 +224,33 @@ jobs: --locale=C ` --pgdata=${Env:PGROONGA_TEST_DATA} ` --username=${Env:PGROONGA_TEST_USER} - Write-Output "max_prepared_transactions = 1" | ` - Out-File ` - -FilePath ${Env:PGROONGA_TEST_DATA}\postgresql.conf ` - -Encoding utf8 ` - -Append + Add-Content ` + -Path ${Env:PGROONGA_TEST_DATA}\postgresql.conf ` + -Value "enable_partitionwise_join = on","max_prepared_transactions = 1","random_page_cost = 0" ` + -Encoding utf8 ..\pgsql\bin\pg_ctl start ` --pgdata=${Env:PGROONGA_TEST_DATA} - - name: Run regression test - # TODO: Remove this when we're PostgreSQL 18 on Windows ready - continue-on-error: ${{ matrix.postgresql-version-major == '18' && true || false }} + - name: Prepare test files run: | # TODO: Remove me when Groonga bundles libstemmer Remove-Item sql\full-text-search\text\options\token-filters\custom.sql # Reduce tests to reduce test time Remove-Item sql\compatibility -Recurse -Force - ruby test\prepare.rb > schedule - $Env:PG_REGRESS_DIFF_OPTS = "-u" - if (${{ matrix.postgresql-version-major }} -ge 17) { - # pg_regress.exe depends on libpq.dll and libpq.dll exists - # in pgsql\bin\. We need to set $Env:PATH or use same - # directory to resolve the dependency. We use the same - # directory approach here. - Copy-Item ` - -Path ..\pgsql\lib\pgxs\src\test\regress\pg_regress.exe ` - ..\pgsql\bin\ - } - ..\pgsql\bin\pg_regress ` - --bindir=..\pgsql\bin ` - --encoding=${Env:PGROONGA_TEST_ENCODING} ` - --launcher=test\short-pgappname.bat ` - --load-extension=pgroonga ` - --schedule=schedule ` - --user=${Env:PGROONGA_TEST_USER} + - name: Run regression test + shell: cmd + run: | + call "%VC_PREFIX%\Auxiliary\Build\vcvars64.bat" + set PGUSER=%PGROONGA_TEST_USER% + meson test -C ..\pgroonga.build -v - name: Shutdown PostgreSQL for test if: always() run: | ..\pgsql\bin\pg_ctl stop ` --pgdata=${Env:PGROONGA_TEST_DATA} - name: Show diff - # TODO: Remove "matrix.postgresql-version-major == '18' ||" when we're PostgreSQL 18 on Windows ready - if: matrix.postgresql-version-major == '18' || failure() + if: failure() run: | - Get-Content regression.diffs + Get-Content ..\pgroonga.build\regression.diffs - uses: actions/checkout@v6 with: repository: pgroonga/benchmark diff --git a/meson.build b/meson.build index 94081164d..a5a03ccd3 100644 --- a/meson.build +++ b/meson.build @@ -8,7 +8,9 @@ required_groonga_version = '14.1.0' groonga = dependency('groonga', version: '>= ' + required_groonga_version) cc = meson.get_compiler('c') -libm = cc.find_library('m') +if host_machine.system() == 'windows' + windows = import('windows') +endif pg_config_path = get_option('pg_config') if pg_config_path == '' @@ -18,6 +20,9 @@ pg_config = find_program(pg_config_path) pg_includedir_server = run_command( pg_config, '--includedir-server', check: true ).stdout().strip() +pg_includedir = run_command( + pg_config, '--includedir', check: true +).stdout().strip() pg_pkglibdir = run_command( pg_config, '--pkglibdir', check: true ).stdout().strip() @@ -29,31 +34,76 @@ pg_bindir = run_command( ).stdout().strip() pg_includedir_extension = pg_includedir_server / 'extension' +pgrn_project_id = meson.project_name() pgrn_version = meson.project_version() + +pgrn_version_components = pgrn_version.split('.') +pgrn_rc_config = { + 'PGRN_VERSION_MAJOR': pgrn_version_components[0], + 'PGRN_VERSION_MINOR': pgrn_version_components[1], + 'PGRN_VERSION_MICRO': pgrn_version_components[2], + 'PGRN_VERSION': pgrn_version, + 'PGRN_VENDOR': 'The PGroonga Project', + 'PGRN_DESCRIPTION': 'Super fast and all languages supported full text search index based on Groonga', + 'PGRN_PROJECT_NAME': 'PGroonga', +} + pgrn_c_args = [f'-DPGRN_VERSION="@pgrn_version@"'] if get_option('buildtype').startswith('debug') pgrn_c_args += ['-DPGROONGA_DEBUG=1'] endif +if host_machine.system() == 'windows' + pgrn_c_args += ['/EHsc'] +endif # Note: Meson's split() is NOT shell-compatible. # It splits only on whitespace and doesn't understand shell quoting. # For example: 'a "b c" d' becomes ['a', '"b', 'c"', 'd'] instead of ['a', 'b c', 'd']. # This works for most PostgreSQL flags but may break with quoted paths containing spaces. # Related upstream issue: https://github.com/mesonbuild/meson/issues/15000 -pg_cppflags = run_command(pg_config, '--cppflags', check: true).stdout().strip().split() -pg_cflags_sl = run_command(pg_config, '--cflags_sl', check: true).stdout().strip().split() +if host_machine.system() == 'windows' + pg_cppflags = [] + pg_cflags_sl = [] +else + pg_cppflags = run_command(pg_config, '--cppflags', check: true).stdout().strip().split() + pg_cflags_sl = run_command(pg_config, '--cflags_sl', check: true).stdout().strip().split() +endif + +pg_include_dirs = [] +if host_machine.system() == 'windows' + # Windows needs port-specific includes first for platform headers + # These provide Windows implementations of Unix headers (netdb.h, etc.) + pg_include_dirs += [ + include_directories(pg_includedir_server / 'port' / 'win32_msvc', is_system: true), + include_directories(pg_includedir_server / 'port' / 'win32', is_system: true), + include_directories(pg_includedir, is_system: true), + ] +endif +pg_include_dirs += [ + include_directories(pg_includedir_server, is_system: true), +] postgresql = declare_dependency( compile_args: pg_cppflags + pg_cflags_sl, - include_directories: [ - include_directories(pg_includedir_server, is_system: true), - ], + include_directories: pg_include_dirs, ) -pgrn_dependencies = [postgresql, groonga, libm] +pgrn_dependencies = [postgresql, groonga] +if host_machine.system() == 'windows' + # On Windows, extensions must explicitly link against postgres.lib + # to access PostgreSQL server functions + postgresql_lib = cc.find_library('postgres', dirs: [pg_pkglibdir]) + pgrn_dependencies += postgresql_lib +else + # On Unix/Linux, link against libm (math library) + libm = cc.find_library('m') + pgrn_dependencies += libm +endif if meson.version().version_compare('>= 0.60.0') - msgpack = dependency('msgpack-c', 'msgpack', required: get_option('message_pack')) + # On Windows, msgpack-c from vcpkg provides CMake config but not pkg-config + pkg_tool = host_machine.system() == 'windows' ? 'cmake' : 'pkg-config' + msgpack = dependency('msgpack-c', 'msgpack', method: pkg_tool, required: get_option('message_pack')) else # We assume that users on environments that use old Meson use old # MessagePack. We don't check 'msgpack-c' here because we don't want @@ -68,14 +118,18 @@ if msgpack.found() pgrn_dependencies += pgrn_msgpack endif -xxhash = dependency('libxxhash', required: get_option('xxhash')) +xxhash = dependency('libxxhash', + required: get_option('xxhash'), + fallback: ['xxhash', 'xxhash_dep']) if xxhash.found() pgrn_dependencies += xxhash endif name_suffix = 'so' -if host_machine.system() == 'darwin' and \ - pg_config.version().version_compare('>= 16') +if host_machine.system() == 'windows' + name_suffix = 'dll' +elif host_machine.system() == 'darwin' and \ + pg_config.version().version_compare('>= 16') name_suffix = 'dylib' endif @@ -134,6 +188,16 @@ pgroonga_sources = files( 'src/pgroonga.c', ) +if host_machine.system() == 'windows' + pgroonga_sources += windows.compile_resources( + configure_file( + input: 'src/pgroonga.rc.in', + output: 'pgroonga.rc', + configuration: pgrn_rc_config + {'PGRN_DLL_NAME': pgrn_project_id} + ) + ) +endif + pgroonga = shared_module('pgroonga', pgroonga_sources, kwargs: pgrn_module_args, @@ -143,6 +207,16 @@ pgroonga_check_sources = files( 'src/pgroonga-check.c', ) +if host_machine.system() == 'windows' + pgroonga_check_sources += windows.compile_resources( + configure_file( + input: 'src/pgroonga-check.rc.in', + output: 'pgroonga-check.rc', + configuration: pgrn_rc_config + {'PGRN_CHECK_DLL_NAME': pgrn_project_id + '_check'} + ) + ) +endif + pgroonga_check = shared_module('pgroonga_check', pgroonga_check_sources, kwargs: pgrn_module_args, @@ -152,6 +226,16 @@ pgroonga_database_sources = files( 'src/pgroonga-database.c', ) +if host_machine.system() == 'windows' + pgroonga_database_sources += windows.compile_resources( + configure_file( + input: 'src/pgroonga-database.rc.in', + output: 'pgroonga-database.rc', + configuration: pgrn_rc_config + {'PGRN_DATABASE_DLL_NAME': pgrn_project_id + '_database'} + ) + ) +endif + pgroonga_database = shared_module('pgroonga_database', pgroonga_database_sources, kwargs: pgrn_module_args, @@ -161,6 +245,16 @@ pgroonga_wal_applier_sources = files( 'src/pgroonga-wal-applier.c', ) +if host_machine.system() == 'windows' + pgroonga_wal_applier_sources += windows.compile_resources( + configure_file( + input: 'src/pgroonga-wal-applier.rc.in', + output: 'pgroonga-wal-applier.rc', + configuration: pgrn_rc_config + {'PGRN_WAL_APPLIER_DLL_NAME': pgrn_project_id + '_wal_applier'} + ) + ) +endif + pgroonga_wal_applier = shared_module('pgroonga_wal_applier', pgroonga_wal_applier_sources, kwargs: pgrn_module_args, @@ -170,6 +264,16 @@ pgroonga_crash_safer_sources = files( 'src/pgroonga-crash-safer.c', ) +if host_machine.system() == 'windows' + pgroonga_crash_safer_sources += windows.compile_resources( + configure_file( + input: 'src/pgroonga-crash-safer.rc.in', + output: 'pgroonga-crash-safer.rc', + configuration: pgrn_rc_config + {'PGRN_CRASH_SAFER_DLL_NAME': pgrn_project_id + '_crash_safer'} + ) + ) +endif + pgroonga_crash_safer = shared_module('pgroonga_crash_safer', pgroonga_crash_safer_sources, kwargs: pgrn_module_args, @@ -179,6 +283,16 @@ pgroonga_standby_maintainer_sources = files( 'src/pgroonga-standby-maintainer.c', ) +if host_machine.system() == 'windows' + pgroonga_standby_maintainer_sources += windows.compile_resources( + configure_file( + input: 'src/pgroonga-standby-maintainer.rc.in', + output: 'pgroonga-standby-maintainer.rc', + configuration: pgrn_rc_config + {'PGRN_STANDBY_MAINTAINER_DLL_NAME': pgrn_project_id + '_standby_maintainer'} + ) + ) +endif + pgroonga_standby_maintainer = shared_module('pgroonga_standby_maintainer', pgroonga_standby_maintainer_sources, kwargs: pgrn_module_args, @@ -188,6 +302,16 @@ pgroonga_wal_resource_manager_sources = files( 'src/pgroonga-wal-resource-manager.c', ) +if host_machine.system() == 'windows' + pgroonga_wal_resource_manager_sources += windows.compile_resources( + configure_file( + input: 'src/pgroonga-wal-resource-manager.rc.in', + output: 'pgroonga-wal-resource-manager.rc', + configuration: pgrn_rc_config + {'PGRN_WAL_RESOURCE_MANAGER_DLL_NAME': pgrn_project_id + '_wal_resource_manager'} + ) + ) +endif + pgroonga_wal_resource_manager = shared_module('pgroonga_wal_resource_manager', pgroonga_wal_resource_manager_sources, kwargs: pgrn_module_args, @@ -429,19 +553,32 @@ install_data(maintainer_scripts, if get_option('test') ruby = find_program('ruby') + # For PostgreSQL 17+ on Windows, pg_regress.exe in pgxs depends on libpq.dll + # which is in the bin directory. We copy pg_regress.exe to bin in CI, + # so search bin directory first for PostgreSQL 17+ on Windows only. + if host_machine.system() == 'windows' and pg_config.version().version_compare('>= 17') + pg_regress_dirs = [ + pg_bindir, + pg_pkglibdir / 'pgxs/src/test/regress', + ] + else + pg_regress_dirs = [ + pg_pkglibdir / 'pgxs/src/test/regress', + pg_bindir, + ] + endif pg_regress = find_program( 'pg_regress', - dirs: [pg_pkglibdir / 'pgxs/src/test/regress'] + dirs: pg_regress_dirs ) - schedule = meson.current_build_dir() / 'schedule' prepare_test = custom_target( 'prepare', output: 'schedule', command: [ ruby, meson.current_source_dir() / 'test' / 'prepare.rb', - schedule + '@OUTPUT@' ], env: { 'BUILD_DIR': meson.current_build_dir(), @@ -449,6 +586,13 @@ if get_option('test') build_always_stale: true ) + schedule = prepare_test.full_path() + + if host_machine.system() == 'windows' + launcher = meson.current_source_dir() / 'test' / 'short-pgappname.bat' + else + launcher = meson.current_source_dir() / 'test' / 'short-pgappname' + endif test('regression', pg_regress, args: [ @@ -456,7 +600,7 @@ if get_option('test') '--dlpath', meson.current_build_dir(), '--inputdir', meson.current_source_dir(), '--outputdir', meson.current_build_dir(), - '--launcher', meson.current_source_dir() / 'test' / 'short-pgappname', + '--launcher', launcher, '--load-extension', meson.project_name(), '--schedule', schedule ], diff --git a/subprojects/xxhash.wrap b/subprojects/xxhash.wrap new file mode 100644 index 000000000..35cfd29d9 --- /dev/null +++ b/subprojects/xxhash.wrap @@ -0,0 +1,13 @@ +[wrap-file] +directory = xxHash-0.8.3 +source_url = https://github.com/Cyan4973/xxHash/archive/v0.8.3.tar.gz +source_filename = xxHash-0.8.3.tar.gz +source_hash = aae608dfe8213dfd05d909a57718ef82f30722c392344583d3f39050c7f29a80 +patch_filename = xxhash_0.8.3-2_patch.zip +patch_url = https://wrapdb.mesonbuild.com/v2/xxhash_0.8.3-2/get_patch +patch_hash = c7f78fc2d08ec21ff1bae928d7bdcddb42713a07d9d973a885c59ea7f8cf6bc8 +source_fallback_url = https://github.com/mesonbuild/wrapdb/releases/download/xxhash_0.8.3-2/xxHash-0.8.3.tar.gz +wrapdb_version = 0.8.3-2 + +[provide] +libxxhash = xxhash_dep