Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
294 changes: 294 additions & 0 deletions .github/workflows/ci-lazypg.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,294 @@
# This workflow will build and test PL/Java against a version of PostgreSQL
# lazily obtained (either preinstalled in the GitHub Actions runner environment,
# or obtained from a package repository if the runner does not provide one).
# Arrange for the matrix to include a pg version, for cases where one must be
# installed.

name: CI lazy getting PostgreSQL

permissions:
contents: read

on:
push:
branches: [ master, REL1_6_STABLE ]
pull_request:
branches: [ master, REL1_6_STABLE ]

jobs:
build:
if: true

runs-on: ${{ matrix.oscc.os }}
continue-on-error: true
strategy:
matrix:
oscc:
- os: ubuntu-latest
cc: gcc
- os: macos-13
cc: clang
pg: 17
- os: macos-14
cc: clang
pg: 17
# - os: windows-latest
# cc: msvc
# - os: windows-latest
# cc: mingw
java: [11, 17, 21, 23]

steps:

- name: Check for JDK preinstalled
id: jdkcheck
shell: bash
env:
JAVAVER: ${{ matrix.java }}
run: |
if
candidate="JAVA_HOME_${JAVAVER}_${RUNNER_ARCH}"
echo -n "Environment contains $candidate? "
[[ -n ${!candidate+set} ]]
then
echo yes
echo >>"$GITHUB_ENV" "JAVA_HOME=${!candidate}"
echo >>"$GITHUB_OUTPUT" java_found=true
elif
candidate="JAVA_HOME_${JAVAVER}_$(tr A-Z a-z <<<${RUNNER_ARCH})"
echo -ne 'no\n'"Environment contains $candidate? "
[[ -n ${!candidate+set} ]]
then
echo yes
echo >>"$GITHUB_ENV" "JAVA_HOME=${!candidate}"
echo >>"$GITHUB_OUTPUT" java_found=true
else
echo -e 'no\n'"only: ${!JAVA_HOME_*}"
echo >>"$GITHUB_OUTPUT" java_found=false
fi

- name: Fetch a JDK
if: ${{ 'false' == steps.jdkcheck.outputs.java_found }}
uses: actions/setup-java@7a6d8a8234af8eb26422e24e3006232cccaa061b
with:
distribution: temurin
java-version: ${{ matrix.java }}

- name: Compute absolute paths for java and jshell
shell: bash
run: |
if [[ $RUNNER_OS == Windows ]]
then
echo >>"$GITHUB_ENV" "ABS_JAVA=$JAVA_HOME"'\bin\java'
echo >>"$GITHUB_ENV" "ABS_JSHELL=$JAVA_HOME"'\bin\jshell'
else
echo >>"$GITHUB_ENV" "ABS_JAVA=$JAVA_HOME/bin/java"
echo >>"$GITHUB_ENV" "ABS_JSHELL=$JAVA_HOME/bin/jshell"
fi

- name: Set PGCONFIG in environment, installing PostgreSQL if needed
shell: bash
env:
PGVER: ${{ matrix.oscc.pg }}
run: |
if [[ $RUNNER_OS == Linux ]]
then
echo >>"$GITHUB_ENV" PGCONFIG=pg_config
elif [[ $RUNNER_OS == Windows ]]
then
echo >>"$GITHUB_ENV" PGCONFIG="$PGBIN"'\pg_config'
elif [[ $RUNNER_OS == macOS ]]
then
echo '::group::brew update'
brew update
echo '::endgroup::'
echo "::group::brew install postgresql@$PGVER"
# HOMEBREW_GITHUB_ACTIONS will suppress the formula's initdb
HOMEBREW_GITHUB_ACTIONS=1 HOMEBREW_NO_INSTALLED_DEPENDENTS_CHECK=1 \
brew install postgresql@"$PGVER"
echo '::endgroup::'
pfx=$(brew --prefix postgresql@"$PGVER")
echo >>"$GITHUB_ENV" PGCONFIG="$pfx/bin/pg_config"
fi

- name: Report Java, Maven, and PostgreSQL versions
shell: bash
run: |
"$ABS_JAVA" -version
mvn --version
"$PGCONFIG"

- name: Obtain PG development files (Ubuntu, PGDG)
if: ${{ 'Linux' == runner.os }}
run: |
pgver=$("$PGCONFIG" --version)
pgver=${pgver##PostgreSQL }
pgver=${pgver%% *}
pgver=${pgver%.*}
echo '::group::Install PGDG key and repo'
curl -s -S https://www.postgresql.org/media/keys/ACCC4CF8.asc |
gpg --dearmor |
sudo dd of=/etc/apt/trusted.gpg.d/apt.postgresql.org.gpg
echo \
deb \
http://apt.postgresql.org/pub/repos/apt \
"$(lsb_release -cs)-pgdg" \
main |
sudo tee /etc/apt/sources.list.d/pgdg.list
echo '::endgroup::'
echo '::group::apt-get update'
sudo apt-get update
echo '::endgroup::'
echo "::group::apt-get install postgresql-server-dev-$pgver"
sudo apt-get install postgresql-server-dev-"$pgver" libkrb5-dev
echo '::endgroup::'

- name: Confirm PostgreSQL development files are present
shell: python
run: |
from os import getenv
from os.path import join
from re import sub
from subprocess import check_output

pgconfig = getenv('PGCONFIG')

def ask_pg_config(what):
return check_output([pgconfig, '--'+what]).splitlines()[0]

pgch = join(ask_pg_config('includedir-server'), b'pg_config.h')

with open(pgch, 'r') as f:
line = [ln for ln in f if ln.startswith('#define PG_VERSION_STR ')][0]

vers = sub(r'#define PG_VERSION_STR "(.*)"\n', r'\1', line)

print('PostgreSQL development files are present:', vers, sep='\n')

- name: Check out PL/Java
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
with:
path: pljava

- name: Build PL/Java (Linux, macOS)
if: ${{ 'Windows' != runner.os }}
working-directory: pljava
run: |
mvn clean install --batch-mode \
-Dpgsql.pgconfig="$PGCONFIG" \
-Psaxon-examples -Ppgjdbc \
-Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn

- name: Build PL/Java (Windows MinGW-w64)
if: ${{ 'Windows' == runner.os && 'mingw' == matrix.oscc.cc }}
working-directory: pljava
#
# GitHub Actions will allow 'bash' as a shell choice, even on a Windows
# runner, in which case it's the bash from Git for Windows. That isn't the
# same as the msys64\usr\bin\bash that we want; what's more, while both
# rely on a cygwin DLL, they don't rely on the same one, and an attempt
# to exec one from the other leads to a "fatal error - cygheap base
# mismatch". So, the bash we want has to be started by something other
# than the bash we've got. In this case, set shell: to a command that
# will use cmd to start the right bash.
#
# Some of the MinGW magic is set up by the bash profile run at "login", so
# bash must be started with -l. That profile ends with a cd $HOME, so to
# avoid changing the current directory, set HOME=. first (credit for that:
# https://superuser.com/a/806371). As set above, . is really the pljava
# working-directory, so the bash script should start by resetting HOME to
# the path of its parent.
#
# The runner is provisioned with a very long PATH that includes separate
# bin directories for pre-provisioned packages. The MinGW profile replaces
# that with a much shorter path, so mvn and pg_config below must be given
# as absolute paths (using M2 and PGBIN supplied in the environment) or
# they won't be found. As long as mvn itself can be found, it is able
# to find java without difficulty, using the JAVA_HOME that is also in
# the environment.
#
# Those existing variables in the environment are all spelled in Windows
# style with drive letters, colons, and backslashes, rather than the MinGW
# unixy style, but the mingw bash doesn't seem to object.
#
# If you use the runner-supplied bash to examine the environment, you will
# see MSYSTEM=MINGW64 already in it, but that apparently is something the
# runner-supplied bash does. It must be set here before invoking the MinGW
# bash directly.
#
env:
HOME: .
MSYSTEM: MINGW64
shell: 'cmd /C "c:\msys64\usr\bin\bash -l "{0}""'
run: |
HOME=$( (cd .. && pwd) )
"$M2"/mvn clean install --batch-mode \
-Dpgsql.pgconfig="$PGCONFIG" \
-Psaxon-examples -Ppgjdbc \
-Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn

- name: Install and test PL/Java
working-directory: pljava
shell: bash
run: |
packageJar=$(find pljava-packaging -name pljava-pg*.jar -print)

mavenRepo="$HOME/.m2/repository"

saxonVer=$(
find "$mavenRepo/net/sf/saxon/Saxon-HE" \
-name 'Saxon-HE-*.jar' -print |
sort |
tail -n 1
)
saxonVer=${saxonVer%/*}
saxonVer=${saxonVer##*/}

jdbcJar=$(
find "$mavenRepo/org/postgresql/postgresql" \
-name 'postgresql-*.jar' -print |
sort |
tail -n 1
)

#
# The runner on a Unix-like OS is running as a non-privileged user, but
# has passwordless sudo available (needed to install the PL/Java files
# into the system directories where the supplied PostgreSQL lives). By
# contrast, on Windows the runner has admin privilege, and can install
# the files without any fuss (but later below, pg_ctl will have to be
# used when starting PostgreSQL; pg_ctl has a Windows-specific ability
# to drop admin privs so postgres will not refuse to start).
#
# The Git for Windows bash environment includes a find command, and the
# things found have unixy paths returned. Make them Windowsy here, with
# a hardcoded assumption they start with /c which should become c: (as
# appears to be the case in the Windows runner currently).
#
echo '::group::Install files from the package jar'
if [[ $RUNNER_OS == Windows ]]
then
pathSep=';'
"$ABS_JAVA" -Dpgconfig="$PGCONFIG" -jar "$packageJar"
function toWindowsPath() {
local p
p="c:${1#/c}"
printf "%s" "${p//\//\\}"
}
jdbcJar="$(toWindowsPath "$jdbcJar")"
mavenRepo="$(toWindowsPath "$mavenRepo")"
else
pathSep=':'
sudo "$ABS_JAVA" -Dpgconfig="$PGCONFIG" -jar "$packageJar"
fi
echo '::endgroup::'

"$ABS_JSHELL" \
-execution local \
"-J--class-path=$packageJar$pathSep$jdbcJar" \
"--class-path=$packageJar" \
"-J--add-modules=java.sql.rowset,jdk.httpserver" \
"-J-Dpgconfig=$PGCONFIG" \
"-J-DmavenRepo=$mavenRepo" \
"-J-DsaxonVer=$saxonVer" \
CI/integration
Loading
Loading