diff --git a/.github/workflows/build-check.yml b/.github/workflows/build-check.yml
new file mode 100644
index 00000000..dbff846a
--- /dev/null
+++ b/.github/workflows/build-check.yml
@@ -0,0 +1,821 @@
+name: build and checks on running xqerl instance
+on:
+ workflow_call:
+ jobs:
+ build_with_erlang_alpine:
+ runs-on: ubuntu-latest
+ timeout-minutes: 10
+ container: erlang:alpine
+ steps:
+ - name: Alpine Deps
+ run: apk add --update grep tar
+ - uses: actions/checkout@v3
+ - name: Restore Cache
+ id: cache-deps
+ uses: actions/cache@v3
+ with:
+ path: _build
+ key: rebar-${{ hashFiles('./rebar.lock') }}
+ - name: Create Cache
+ if: steps.cache-deps.outputs.cache-hit != 'true'
+ run: |
+ rebar3 deps
+ rebar3 compile
+ - name: Build Production Tar
+ run: |
+ # get grep with perl regx
+ apk add --update grep tar
+ ls .
+ cat /etc/os-release
+ OTP_VERSION=$(cat /usr/local/lib/erlang/releases/*/OTP_VERSION)
+ OS_VERSION=$(cat /etc/os-release | grep -oP 'VERSION_ID=\K.+')
+ XQERL_VERSION=$(grep -oP 'v\d+\.\d+\.\d+' rebar.config)
+ echo " - xqerl release version: ${XQERL_VERSION}"
+ echo " - uses erlang OTP version: ${OTP_VERSION}"
+ echo " - uses alpine version: ${OS_VERSION}"
+ rebar3 as prod tar
+ mkdir -p _release
+ mv _build/prod/rel/xqerl/xqerl-${XQERL_VERSION}.tar.gz _release/xqerl.tar.gz
+ - name: Untar Then Run XQerl
+ run: "mkdir /usr/local/xqerl\ntar -zxf _release/xqerl.tar.gz -C /usr/local/xqerl\ncd
+ /usr/local/bin\nln -s /usr/local/xqerl/bin/xqerl\ncd ~/\nxqerl daemon\nsleep
+ 5\necho -n ' - xqerl application started: '\nxqerl eval 'application:ensure_all_started(xqerl).'
+ | grep -oP 'ok'\nxqerl eval \"file:make_symlink(code:priv_dir(xqerl),\\\"./priv\\\").\"
+ \necho -n ' - network ping: '\nxqerl ping | grep -oP 'pong'\n"
+ - name: Upload built artifact
+ uses: actions/upload-artifact@v3
+ with:
+ name: xqerl-prod-tar
+ path: _release/
+ xqerl_eval_checks:
+ if: ${{ github.ref_type == 'branch' }}
+ needs: build_with_erlang_alpine
+ runs-on: ubuntu-latest
+ timeout-minutes: 10
+ container: erlang:alpine
+ steps:
+ - name: Alpine Deps
+ run: apk add --update grep curl
+ - uses: actions/checkout@v3
+ - uses: actions/download-artifact@v3
+ with:
+ name: xqerl-prod-tar
+ - name: Unpack release tar and install xqerl application
+ run: |
+ mkdir /usr/local/xqerl
+ tar -zxf xqerl.tar.gz -C /usr/local/xqerl
+ cd /usr/local/bin
+ ln -s /usr/local/xqerl/bin/xqerl
+ cd ~/
+ which xqerl
+ xqerl daemon
+ sleep 2
+ - name: Checks - xqerl eval on running instance
+ run: "xqerl eval \"file:make_symlink(code:priv_dir(xqerl),\\\"./priv\\\").\"
+ \necho -n ' - set xqerl working directory: '\nxqerl eval \"file:set_cwd('$(pwd)').\"\nxqerl
+ eval 'file:get_cwd().'\nprintf %60s | tr ' ' '-' && echo\necho ' - run a
+ xQuery expression'\nxqerl eval 'xqerl:run(\"xs:token(\\\"cats\\\"), xs:string(\\\"dogs\\\"),
+ true() \").' | \\\ngrep -oP '^\\[\\{xq.+$'\nprintf %60s | tr ' ' '-' &&
+ echo\necho ' - compile an xQuery file'\nxqerl eval 'xqerl:compile(\"docs/src/sudoku2.xq\").'
+ | \\\ngrep -oP 'file(.+)\\.xq'\nprintf %60s | tr ' ' '-' && echo\necho '
+ - compile, run then grep the title'\nxqerl eval 'S = xqerl:compile(\"docs/src/sudoku2.xq\"),binary_to_list(xqerl_node:to_xml(S:main(#{}))).'
+ | \\\ngrep -oP '
(.+)'\nprintf %60s | tr ' ' '-' && echo\necho
+ -n ' - load an XML file into the DB: '\nxqerl eval \\\n'xqldb_dml:insert_doc(\"http://xqerl.org/my_doc.xml\",\"./test/QT3-test-suite/app/FunctxFn/functx_order.xml\").'
+ | \\\ngrep -oP 'ok'\nprintf %60s | tr ' ' '-' && echo\necho ' - view using
+ the the xqerl:run/1 function with xQuery fn:doc#1 function'\nxqerl eval
+ \"binary_to_list(xqerl:run(\\\" 'http://xqerl.org/my_doc.xml' => doc() =>
+ serialize() \\\")).\"\nprintf %60s | tr ' ' '-' && echo\necho -n ' - delete
+ db doc '\nxqerl eval 'xqldb_dml:delete_doc(\"http://xqerl.org/my_doc.xml\").'
+ | \\\ngrep -oP 'ok'\nprintf %60s | tr ' ' '-' && echo\necho -n ' - import
+ into DB docs from directory: '\nxqerl eval 'xqldb_dml:import_from_directory(\"http://xqerl.org/tests/\",
+ \"./test/QT3-test-suite\").' | \\\ngrep -oP 'ok'\nprintf %60s | tr ' ' '='
+ && echo\n"
+ - name: Checks - Features and Issue Resolution
+ run: |
+ printf %60s | tr ' ' '=' && echo
+ printf %60s | tr ' ' '=' && echo
+ - name: cowboy static assets handler - issue 46
+ run: |
+ echo '- use curl to check if image in priv/static/assets dir is reachable'
+ printf %60s | tr ' ' '=' && echo
+ curl -sSL -D - http://localhost:8081/assets/images/logo.png -o /dev/null
+ curl -sSL -D - http://localhost:8081/assets/images/logo.png -o /dev/null | grep -q '200'
+ printf %60s | tr ' ' '=' && echo
+ - name: after install have a xqerl greeter - issue 48
+ run: |
+ echo '- use curl to check if http://localhost:8081/xqerl is reachable'
+ printf %60s | tr ' ' '=' && echo
+ curl -sSL -D - http://localhost:8081/xqerl -o /dev/null
+ printf %60s | tr ' ' '=' && echo
+ curl -sS http://localhost:8081/xqerl | grep -oP '.+'
+ printf %60s | tr ' ' '=' && echo
+ - name: maintain builtin routes - issue 66
+ run: |
+ echo ' - add restXQ route, then check if greeter service still available'
+ xqerl eval 'xqerl:compile("test/restxq/tests.xqm").'
+ sleep 1
+ curl -sSL -D - http://localhost:8081/xqerl -o /dev/null
+ curl -sS http://localhost:8081/xqerl | grep -oP '.+'
+ rest_db_checks:
+ if: ${{ github.ref_type == 'branch' }}
+ needs: build_with_erlang_alpine
+ runs-on: ubuntu-latest
+ timeout-minutes: 10
+ container: erlang:alpine
+ steps:
+ - name: Alpine Deps
+ run: apk add --update grep curl jq
+ - uses: actions/checkout@v3
+ - uses: actions/download-artifact@v3
+ with:
+ name: xqerl-prod-tar
+ - name: Unpack release tar and install xqerl application
+ run: "mkdir /usr/local/xqerl\ntar -zxf xqerl.tar.gz -C /usr/local/xqerl\ncd
+ /usr/local/bin\nln -s /usr/local/xqerl/bin/xqerl\ncd ~/\nxqerl daemon\nsleep
+ 5\nxqerl eval \"file:make_symlink(code:priv_dir(xqerl),\\\"./priv\\\").\"
+ \necho -n ' - set xqerl working directory: '\nxqerl eval \"file:set_cwd('$(pwd)').\"\n"
+ - name: POST XML, create XDM document-node resource
+ run: |
+ CHECK=POST_XML_DATA
+ COLLECTION=example.com/docs
+ RESOURCE=doc-data.xml
+ CHECK_PATH=checks/${CHECK}/${COLLECTION}
+ mkdir -p $CHECK_PATH
+ curl --silent --show-error --connect-timeout 1 --max-time 2 \
+ --dump-header ${CHECK_PATH}/headers.txt \
+ --write-out '\nresponse code [ %{http_code} ]\n' \
+ --header 'Content-Type: application/xml' \
+ --header "Slug: ${RESOURCE}" \
+ --data 'data' \
+ http://localhost:8081/db/${COLLECTION} > ${CHECK_PATH}/write-out.txt
+ printf %60s | tr ' ' '=' && echo
+ echo ' - show headers'
+ echo ' ---------------'
+ cat ${CHECK_PATH}/headers.txt
+ printf %60s | tr ' ' '=' && echo
+ echo ' - show write out'
+ echo ' ----------------'
+ cat ${CHECK_PATH}/write-out.txt && echo
+ printf %60s | tr ' ' '=' && echo
+ echo '- response should return ok created status'
+ cat ${CHECK_PATH}/write-out.txt | grep -oP 'response code \[ 201 \]'
+ echo '- response headers should include a location header'
+ cat ${CHECK_PATH}/headers.txt | grep -oP '^location.+$'
+ printf %60s | tr ' ' '='
+ - name: POST JSON array create XDM array resource
+ run: |
+ CHECK=POST_JSON_ARRAY
+ COLLECTION=example.com/docs
+ RESOURCE=json-data.array
+ CHECK_PATH=checks/${CHECK}/${COLLECTION}
+ mkdir -p $CHECK_PATH
+ curl --silent --show-error --connect-timeout 1 --max-time 2 \
+ --dump-header ${CHECK_PATH}/headers.txt \
+ --write-out '\nresponse code [ %{http_code} ]\n' \
+ --header 'Content-Type: application/json' \
+ --header "Slug: ${RESOURCE}" \
+ --data '[1,2,3]' \
+ http://localhost:8081/db/${COLLECTION} > ${CHECK_PATH}/write-out.txt
+ printf %60s | tr ' ' '=' && echo
+ echo ' - show headers'
+ echo ' ---------------'
+ cat ${CHECK_PATH}/headers.txt
+ printf %60s | tr ' ' '=' && echo
+ echo ' - show write out'
+ echo ' ----------------'
+ cat ${CHECK_PATH}/write-out.txt && echo
+ printf %60s | tr ' ' '=' && echo
+ echo '- response should return ok created status'
+ grep -q 'response code \[ 201 \]' ${CHECK_PATH}/write-out.txt
+ echo '- response headers should include a location header'
+ grep -qP '^location.+$' ${CHECK_PATH}/headers.txt
+ printf %60s | tr ' ' '='
+ - name: POST JSON object create XDM map resource
+ run: |
+ CHECK=POST_JSON_MAP
+ COLLECTION=example.com/docs
+ RESOURCE=json-data.map
+ CHECK_PATH=checks/${CHECK}/${COLLECTION}
+ mkdir -p $CHECK_PATH
+ curl --silent --show-error --connect-timeout 1 --max-time 2 \
+ --dump-header ${CHECK_PATH}/headers.txt \
+ --write-out '\nresponse code [ %{http_code} ]\n' \
+ --header 'Content-Type: application/json' \
+ --header "Slug: ${RESOURCE}" \
+ --data '{"check": "mate"}' \
+ http://localhost:8081/db/${COLLECTION} > ${CHECK_PATH}/write-out.txt
+ printf %60s | tr ' ' '=' && echo
+ echo ' - show headers'
+ echo ' ---------------'
+ cat ${CHECK_PATH}/headers.txt
+ printf %60s | tr ' ' '=' && echo
+ echo ' - show write out'
+ echo ' ----------------'
+ cat ${CHECK_PATH}/write-out.txt
+ printf %60s | tr ' ' '=' && echo
+ echo '- response should return ok created status'
+ grep -q 'response code \[ 201 \]' ${CHECK_PATH}/write-out.txt
+ echo '- response headers should include a location header'
+ grep -qP '^location.+$' ${CHECK_PATH}/headers.txt
+ printf %60s | tr ' ' '='
+ - name: POST CSV create XDM array resource
+ run: |
+ CHECK=POST_CSV
+ COLLECTION=example.com/docs
+ RESOURCE=csv-data.array
+ CHECK_PATH=checks/${CHECK}/${COLLECTION}
+ mkdir -p $CHECK_PATH
+ cat << EOF > $CHECK_PATH/data.csv
+ GID,On Street,Species,Trim Cycle,Inventory Date
+ 1,ADDISON AV,Celtis australis,Large Tree Routine Prune,10/18/2010
+ 2,EMERSON ST,Liquidambar styraciflua,Large Tree Routine Prune,6/2/2010
+ EOF
+ curl --silent --show-error --connect-timeout 1 --max-time 2 \
+ --dump-header ${CHECK_PATH}/headers.txt \
+ --write-out '\nresponse code [ %{http_code} ]\n' \
+ --header 'Content-Type: text/csv' \
+ --header "Slug: ${RESOURCE}" \
+ --data-binary "@${CHECK_PATH}/data.csv" \
+ http://localhost:8081/db/${COLLECTION} > ${CHECK_PATH}/write-out.txt
+ printf %60s | tr ' ' '=' && echo
+ echo ' - show headers'
+ echo ' ---------------'
+ cat ${CHECK_PATH}/headers.txt
+ printf %60s | tr ' ' '=' && echo
+ echo ' - show write out'
+ echo ' ----------------'
+ cat ${CHECK_PATH}/write-out.txt
+ printf %60s | tr ' ' '=' && echo
+ echo '- response should return ok created status'
+ grep -q 'response code \[ 201 \]' ${CHECK_PATH}/write-out.txt
+ echo '- response headers should include a location header'
+ grep -qP '^location.+$' ${CHECK_PATH}/headers.txt
+ sleep 1
+ printf %60s | tr ' ' '='
+ - name: POST - unsupported media type
+ run: |
+ CHECK=POST_MSWORD
+ COLLECTION=example.com/docs
+ RESOURCE=foo.data
+ CHECK_PATH=checks/${CHECK}/${COLLECTION}
+ mkdir -p $CHECK_PATH
+ curl --silent --show-error --connect-timeout 1 --max-time 2 \
+ --dump-header ${CHECK_PATH}/headers.txt \
+ --write-out '\nresponse code [ %{http_code} ]\n' \
+ --header 'Content-Type: application/msword' \
+ --header "Slug: ${RESOURCE}" \
+ --data 'foo' \
+ http://localhost:8081/db/${COLLECTION} > ${CHECK_PATH}/write-out.txt
+ printf %60s | tr ' ' '=' && echo
+ echo ' - show headers'
+ echo ' ---------------'
+ cat ${CHECK_PATH}/headers.txt
+ printf %60s | tr ' ' '=' && echo
+ echo ' - show write out'
+ echo ' ----------------'
+ cat ${CHECK_PATH}/write-out.txt
+ printf %60s | tr ' ' '=' && echo
+ echo '- headers should return "Unsupported Media Type" status'
+ grep -qoP 'HTTP(.+)415(.+)' ${CHECK_PATH}/headers.txt
+ printf %60s | tr ' ' '=' && echo
+ - name: GET - list resources in database collection as text
+ run: |
+ CHECK=GET_LIST_COLLECTION_RESOURCES_AS_TEXT
+ CHECK_PATH=checks/${CHECK}/example.com/docs
+ mkdir -p $CHECK_PATH
+ curl --silent --show-error --connect-timeout 1 --max-time 2 \
+ --header "Accept: text/plain" \
+ --dump-header ${CHECK_PATH}/headers.txt \
+ --write-out 'response code [ %{http_code} ]\ncontent type [ %{content_type} ]\n' \
+ --output ${CHECK_PATH}/output.txt \
+ http://localhost:8081/db/example.com/docs > ${CHECK_PATH}/write-out.txt
+ echo ' - show headers'
+ echo ' ---------------'
+ cat ${CHECK_PATH}/headers.txt
+ echo '- content-type should be text/plain'
+ grep -oP 'content-type: text/plain' ${CHECK_PATH}/headers.txt
+ printf %60s | tr ' ' '=' && echo
+ echo ' - show write out'
+ echo ' ----------------'
+ cat ${CHECK_PATH}/write-out.txt && echo
+ printf %60s | tr ' ' '=' && echo
+ echo ' - show output text'
+ echo ' ---------------'
+ cat ${CHECK_PATH}/output.txt && echo
+ printf %60s | tr ' ' '=' && echo
+ echo '- response should return ok created status'
+ grep -oP 'response code \[ 200 \]' ${CHECK_PATH}/write-out.txt
+ printf %60s | tr ' ' '=' && echo
+ - name: GET - list resources in database collection as json
+ run: |
+ CHECK=GET_LIST_COLLECTION_RESOURCES_AS_JSON
+ CHECK_PATH=checks/${CHECK}/example.com/docs
+ mkdir -p $CHECK_PATH
+ curl --silent --show-error --connect-timeout 1 --max-time 2 \
+ --header "Accept: application/json" \
+ --dump-header ${CHECK_PATH}/headers.txt \
+ --write-out 'response code [ %{http_code} ]\ncontent type [ %{content_type} ]\n' \
+ --output ${CHECK_PATH}/output.txt \
+ http://localhost:8081/db/example.com/docs > ${CHECK_PATH}/write-out.txt
+ echo ' - show headers'
+ echo ' ---------------'
+ cat ${CHECK_PATH}/headers.txt
+ echo '- content-type should be application/json'
+ grep -oP 'content-type: application/json' ${CHECK_PATH}/headers.txt
+ printf %60s | tr ' ' '=' && echo
+ echo ' - show write out'
+ echo ' ----------------'
+ cat ${CHECK_PATH}/write-out.txt && echo
+ printf %60s | tr ' ' '=' && echo
+ echo ' - show output as json'
+ echo ' ---------------'
+ jq '.' ${CHECK_PATH}/output.txt && echo
+ printf %60s | tr ' ' '=' && echo
+ echo '- response should return ok created status'
+ grep -oP 'response code \[ 200 \]' ${CHECK_PATH}/write-out.txt
+ printf %60s | tr ' ' '=' && echo
+ - name: OPTIONS - allowable methods for collection
+ run: |
+ CHECK=OPTIONS_COLLECTION
+ COLLECTION=example.com/docs
+ CHECK_PATH=checks/${CHECK}/${COLLECTION}
+ mkdir -p $CHECK_PATH
+ curl --silent --show-error --connect-timeout 1 --max-time 2 \
+ -X OPTIONS \
+ --dump-header ${CHECK_PATH}/headers.txt \
+ --write-out 'response code [ %{http_code} ]\ncontent type [ %{content_type} ]' \
+ http://localhost:8081/db/${COLLECTION} > ${CHECK_PATH}/write-out.txt
+ printf %60s | tr ' ' '=' && echo
+ echo ' - show headers'
+ echo ' ---------------'
+ cat ${CHECK_PATH}/headers.txt
+ printf %60s | tr ' ' '=' && echo
+ echo ' - show write out'
+ echo ' ----------------'
+ cat ${CHECK_PATH}/write-out.txt && echo
+ printf %60s | tr ' ' '=' && echo
+ echo '- headers should return ok status'
+ grep -oP 'HTTP(.+)200(.+)' ${CHECK_PATH}/headers.txt
+ printf %60s | tr ' ' '=' && echo
+ echo '- headers should have allow options'
+ grep -oP 'allow:(.+)' ${CHECK_PATH}/headers.txt
+ printf %60s | tr ' ' '=' && echo
+ - name: HEAD - database collection available accept text
+ run: |
+ # NOTE: the use of the accept HEADER
+ CHECK=HEAD_COLLECTION_AVAILABLE
+ COLLECTION=example.com/docs
+ CHECK_PATH=checks/${CHECK}/${COLLECTION}
+ mkdir -p $CHECK_PATH
+ curl --silent --show-error --connect-timeout 1 --max-time 2 \
+ --dump-header ${CHECK_PATH}/headers.txt \
+ --write-out '\nresponse code [ %{http_code} ]\ncontent type [ %{content_type} ]' \
+ --head -H 'Accept: text/plain' \
+ http://localhost:8081/db/${COLLECTION} > ${CHECK_PATH}/write-out.txt
+ printf %60s | tr ' ' '=' && echo
+ echo ' - show headers'
+ echo ' ---------------'
+ cat ${CHECK_PATH}/headers.txt
+ printf %60s | tr ' ' '=' && echo
+ echo ' - show write out'
+ echo ' ----------------'
+ cat ${CHECK_PATH}/write-out.txt && echo
+ printf %60s | tr ' ' '=' && echo
+ echo '- response should return ok status'
+ grep -oP 'response code \[ 200 \]' ${CHECK_PATH}/write-out.txt
+ - name: HEAD - database collection available accept xml
+ run: |
+ # NOTE: the use of the accept HEADER
+ CHECK=HEAD_COLLECTION_AVAILABLE
+ COLLECTION=example.com/docs
+ CHECK_PATH=checks/${CHECK}/${COLLECTION}
+ mkdir -p $CHECK_PATH
+ curl --silent --show-error --connect-timeout 1 --max-time 2 \
+ --dump-header ${CHECK_PATH}/headers.txt \
+ --write-out '\nresponse code [ %{http_code} ]\ncontent type [ %{content_type} ]' \
+ --head -H 'Accept: application/xml' \
+ http://localhost:8081/db/${COLLECTION} > ${CHECK_PATH}/write-out.txt
+ printf %60s | tr ' ' '=' && echo
+ echo ' - show headers'
+ echo ' ---------------'
+ cat ${CHECK_PATH}/headers.txt
+ printf %60s | tr ' ' '=' && echo
+ echo ' - show write out'
+ echo ' ----------------'
+ cat ${CHECK_PATH}/write-out.txt && echo
+ printf %60s | tr ' ' '=' && echo
+ echo '- response should return ok status'
+ grep -oP 'response code \[ 200 \]' ${CHECK_PATH}/write-out.txt
+ - name: HEAD - database resource available
+ run: |
+ CHECK=HEAD_RESOURCE_AVAILABLE
+ COLLECTION=example.com/docs
+ RESOURCE=doc-data.xml
+ CHECK_PATH=checks/${CHECK}/${COLLECTION}
+ mkdir -p $CHECK_PATH
+ curl --silent --show-error --connect-timeout 1 --max-time 2 \
+ --dump-header ${CHECK_PATH}/headers.txt \
+ --write-out '\nresponse code [ %{http_code} ]\ncontent type [ %{content_type} ]\n' \
+ --head -H 'Accept: application/xml' \
+ http://localhost:8081/db/${COLLECTION}/${RESOURCE} > ${CHECK_PATH}/write-out.txt
+ printf %60s | tr ' ' '=' && echo
+ echo ' - show headers'
+ echo ' ---------------'
+ cat ${CHECK_PATH}/headers.txt
+ echo && printf %60s | tr ' ' '=' && echo
+ echo ' - show write out'
+ echo ' ----------------'
+ cat ${CHECK_PATH}/write-out.txt
+ printf %60s | tr ' ' '=' && echo
+ echo '- response should return ok status'
+ grep -oP 'response code \[ 200 \]' ${CHECK_PATH}/write-out.txt
+ echo ' NOTE; head request can be used to get content size'
+ echo ' - header should return content length'
+ grep -oP 'content-length(.+)' ${CHECK_PATH}/headers.txt
+ if grep -oP 'content-length: 0' ${CHECK_PATH}/headers.txt >/dev/null
+ then
+ echo ' - header content length should be greater than zero: false'
+ false
+ else
+ echo ' - header content length should be greater than zero: true'
+ fi
+ printf %60s | tr ' ' '=' && echo
+ # NOTE: resource retrieval via Accept Header
+ - name: GET - accept XML - retrieve XDM document-node resource
+ run: |
+ CHECK=GET_ACCEPT_XML
+ COLLECTION=example.com/docs
+ RESOURCE=doc-data.xml
+ CHECK_PATH=checks/${CHECK}/${COLLECTION}
+ mkdir -p $CHECK_PATH
+ curl --silent --show-error --connect-timeout 1 --max-time 2 \
+ --header 'Accept: application/xml' \
+ --dump-header ${CHECK_PATH}/headers.txt \
+ --write-out 'response code [ %{http_code} ]\ncontent type [ %{content_type} ]\n' \
+ --output ${CHECK_PATH}/${RESOURCE} \
+ http://localhost:8081/db/${COLLECTION}/${RESOURCE} > ${CHECK_PATH}/write-out.txt
+ printf %60s | tr ' ' '=' && echo
+ echo ' - show data'
+ echo ' ---------------'
+ cat ${CHECK_PATH}/${RESOURCE} && echo
+ printf %60s | tr ' ' '=' &&
+ echo ' - show headers'
+ echo ' ---------------'
+ cat ${CHECK_PATH}/headers.txt
+ echo && printf %60s | tr ' ' '=' && echo
+ echo ' - show write out'
+ echo ' ----------------'
+ cat ${CHECK_PATH}/write-out.txt
+ printf %60s | tr ' ' '=' && echo
+ echo '- headers should return ok status'
+ grep -oP 'HTTP(.+)200(.+)' ${CHECK_PATH}/headers.txt
+ printf %60s | tr ' ' '=' && echo
+ - name: GET - accept JSON - retrieve XDM array resource
+ run: |
+ CHECK=GET_ACCEPT_JSON_ARRAY
+ COLLECTION=example.com/docs
+ RESOURCE=json-data.array
+ CHECK_PATH=checks/${CHECK}/${COLLECTION}
+ mkdir -p $CHECK_PATH
+ curl --silent --show-error --connect-timeout 1 --max-time 2 \
+ --header 'Accept: application/json' \
+ --dump-header ${CHECK_PATH}/headers.txt \
+ --write-out 'response code [ %{http_code} ]\ncontent type [ %{content_type} ]\n' \
+ --output ${CHECK_PATH}/${RESOURCE} \
+ http://localhost:8081/db/${COLLECTION}/${RESOURCE} > ${CHECK_PATH}/write-out.txt
+ printf %60s | tr ' ' '=' && echo
+ echo ' - show data'
+ echo ' ---------------'
+ cat ${CHECK_PATH}/${RESOURCE} && echo
+ printf %60s | tr ' ' '=' &&
+ echo ' - show headers'
+ echo ' ---------------'
+ cat ${CHECK_PATH}/headers.txt
+ echo && printf %60s | tr ' ' '=' && echo
+ echo ' - show write out'
+ echo ' ----------------'
+ cat ${CHECK_PATH}/write-out.txt
+ printf %60s | tr ' ' '=' && echo
+ echo '- headers should return ok status'
+ grep -oP 'HTTP(.+)200(.+)' ${CHECK_PATH}/headers.txt
+ printf %60s | tr ' ' '=' && echo
+ - name: GET - accept JSON - retrieve XDM map resource
+ run: |
+ CHECK=GET_ACCEPT_JSON_MAP
+ COLLECTION=example.com/docs
+ RESOURCE=json-data.map
+ CHECK_PATH=checks/${CHECK}/${COLLECTION}
+ mkdir -p $CHECK_PATH
+ curl --silent --show-error --connect-timeout 1 --max-time 2 \
+ --header 'Accept: application/json' \
+ --dump-header ${CHECK_PATH}/headers.txt \
+ --write-out 'response code [ %{http_code} ]\ncontent type [ %{content_type} ]\n' \
+ --output ${CHECK_PATH}/${RESOURCE} \
+ http://localhost:8081/db/${COLLECTION}/${RESOURCE} > ${CHECK_PATH}/write-out.txt
+ printf %60s | tr ' ' '=' && echo
+ echo ' - show data'
+ echo ' ---------------'
+ cat ${CHECK_PATH}/${RESOURCE} && echo
+ printf %60s | tr ' ' '=' &&
+ echo ' - show headers'
+ echo ' ---------------'
+ cat ${CHECK_PATH}/headers.txt
+ echo && printf %60s | tr ' ' '=' && echo
+ echo ' - show write out'
+ echo ' ----------------'
+ cat ${CHECK_PATH}/write-out.txt
+ printf %60s | tr ' ' '=' && echo
+ echo '- headers should return ok status'
+ grep -oP 'HTTP(.+)200(.+)' ${CHECK_PATH}/headers.txt
+ printf %60s | tr ' ' '=' && echo
+ - name: GET - tabular data - ask for JSON, origin posted CSV data
+ run: |
+ CHECK=CHECK=GET_ACCEPT_JSON_TABULAR_DATA
+ COLLECTION=example.com/docs
+ RESOURCE=csv-data.array
+ CHECK_PATH=checks/${CHECK}/${COLLECTION}
+ mkdir -p $CHECK_PATH
+ curl --silent --show-error --connect-timeout 1 --max-time 2 \
+ --header 'Accept: application/json' \
+ --dump-header ${CHECK_PATH}/headers.txt \
+ --write-out 'response code [ %{http_code} ]\ncontent type [ %{content_type} ]\n' \
+ --output ${CHECK_PATH}/${RESOURCE} \
+ http://localhost:8081/db/${COLLECTION}/${RESOURCE} > ${CHECK_PATH}/write-out.txt
+ printf %60s | tr ' ' '=' && echo
+ echo ' - show data'
+ echo ' ---------------'
+ jq '.' ${CHECK_PATH}/${RESOURCE}
+ printf %60s | tr ' ' '=' &&
+ echo ' - show headers'
+ echo ' ---------------'
+ cat ${CHECK_PATH}/headers.txt
+ echo && printf %60s | tr ' ' '=' && echo
+ echo ' - show write out'
+ echo ' ----------------'
+ cat ${CHECK_PATH}/write-out.txt
+ printf %60s | tr ' ' '=' && echo
+ echo '- headers should return ok status'
+ grep -oP 'HTTP(.+)200(.+)' ${CHECK_PATH}/headers.txt
+ printf %60s | tr ' ' '=' && echo
+ - name: GET - tabular data metadata - ask for JSON, origin posted CSV data
+ run: |
+ CHECK=GET_ACCEPT_JSON_TABULAR_METADATA
+ COLLECTION=example.com/docs
+ RESOURCE=csv-data.array-metadata.json
+ CHECK_PATH=checks/${CHECK}/${COLLECTION}
+ mkdir -p $CHECK_PATH
+ curl --silent --show-error --connect-timeout 1 --max-time 2 \
+ --header 'Accept: application/json' \
+ --dump-header ${CHECK_PATH}/headers.txt \
+ --write-out 'response code [ %{http_code} ]\ncontent type [ %{content_type} ]\n' \
+ --output ${CHECK_PATH}/${RESOURCE} \
+ http://localhost:8081/db/${COLLECTION}/${RESOURCE} > ${CHECK_PATH}/write-out.txt
+ printf %60s | tr ' ' '=' && echo
+ echo ' - show data'
+ echo ' ---------------'
+ jq '.' ${CHECK_PATH}/${RESOURCE}
+ printf %60s | tr ' ' '=' && echo
+ echo ' - show headers'
+ echo ' ---------------'
+ cat ${CHECK_PATH}/headers.txt
+ echo && printf %60s | tr ' ' '=' && echo
+ echo ' - show write out'
+ echo ' ----------------'
+ cat ${CHECK_PATH}/write-out.txt
+ printf %60s | tr ' ' '=' && echo
+ echo '- headers should return ok status'
+ grep -oP 'HTTP(.+)200(.+)' ${CHECK_PATH}/headers.txt
+ printf %60s | tr ' ' '=' && echo
+ - name: GET - tabular data - ask for HTML, origin posted CSV data
+ run: |
+ CHECK=CHECK=GET_ACCEPT_HTML_TABULAR_DATA
+ COLLECTION=example.com/docs
+ RESOURCE=csv-data.array
+ CHECK_PATH=checks/${CHECK}/${COLLECTION}
+ mkdir -p $CHECK_PATH
+ curl --silent --show-error --connect-timeout 1 --max-time 2 \
+ --header 'Accept: text/html' \
+ --dump-header ${CHECK_PATH}/headers.txt \
+ --write-out 'response code [ %{http_code} ]\ncontent type [ %{content_type} ]\n' \
+ --output ${CHECK_PATH}/${RESOURCE} \
+ http://localhost:8081/db/${COLLECTION}/${RESOURCE} > ${CHECK_PATH}/write-out.txt
+ printf %60s | tr ' ' '=' && echo
+ echo ' - show data'
+ echo ' ---------------'
+ cat ${CHECK_PATH}/${RESOURCE}
+ echo && printf %60s | tr ' ' '=' &&
+ echo ' - show headers'
+ echo ' ---------------'
+ cat ${CHECK_PATH}/headers.txt
+ echo && printf %60s | tr ' ' '=' && echo
+ echo ' - show write out'
+ echo ' ----------------'
+ cat ${CHECK_PATH}/write-out.txt
+ printf %60s | tr ' ' '=' && echo
+ echo '- headers should return ok status'
+ grep -oP 'HTTP(.+)200(.+)' ${CHECK_PATH}/headers.txt
+ printf %60s | tr ' ' '=' && echo
+ - name: GET - tabular data - ask for CSV text, origin posted CSV data
+ run: |
+ CHECK=CHECK=GET_ACCEPT_CSV_TABULAR_DATA
+ COLLECTION=example.com/docs
+ RESOURCE=csv-data.array
+ CHECK_PATH=checks/${CHECK}/${COLLECTION}
+ mkdir -p $CHECK_PATH
+ curl --silent --show-error --connect-timeout 1 --max-time 2 \
+ --header 'Accept: text/csv' \
+ --dump-header ${CHECK_PATH}/headers.txt \
+ --write-out 'response code [ %{http_code} ]\ncontent type [ %{content_type} ]\n' \
+ --output ${CHECK_PATH}/${RESOURCE} \
+ http://localhost:8081/db/${COLLECTION}/${RESOURCE} > ${CHECK_PATH}/write-out.txt
+ printf %60s | tr ' ' '=' && echo
+ echo ' - show data'
+ echo ' ---------------'
+ cat ${CHECK_PATH}/${RESOURCE}
+ echo && printf %60s | tr ' ' '=' &&
+ echo ' - show headers'
+ echo ' ---------------'
+ cat ${CHECK_PATH}/headers.txt
+ echo && printf %60s | tr ' ' '=' && echo
+ echo ' - show write out'
+ echo ' ----------------'
+ cat ${CHECK_PATH}/write-out.txt
+ printf %60s | tr ' ' '=' && echo
+ echo '- headers should return ok status'
+ grep -oP 'HTTP(.+)200(.+)' ${CHECK_PATH}/headers.txt
+ printf %60s | tr ' ' '=' && echo
+ - name: GET - unknown resource in collection
+ run: |
+ CHECK=GET_UKNOWN_RESOURCE
+ COLLECTION=example.com/docs
+ RESOURCE=erewhon.xml
+ CHECK_PATH=checks/${CHECK}/${COLLECTION}
+ mkdir -p $CHECK_PATH
+ curl --silent --show-error --connect-timeout 1 --max-time 2 \
+ --dump-header ${CHECK_PATH}/headers.txt \
+ --write-out 'response code [ %{http_code} ]\ncontent type [ %{content_type} ]\n' \
+ http://localhost:8081/db/${COLLECTION}/${RESOURCE} > ${CHECK_PATH}/write-out.txt
+ printf %60s | tr ' ' '=' &&
+ echo ' - show headers'
+ echo ' ---------------'
+ cat ${CHECK_PATH}/headers.txt
+ echo && printf %60s | tr ' ' '=' && echo
+ echo ' - show write out'
+ echo ' ----------------'
+ cat ${CHECK_PATH}/write-out.txt
+ printf %60s | tr ' ' '=' && echo
+ echo '- headers should return not found status'
+ grep -oP 'HTTP(.+)404(.+)' ${CHECK_PATH}/headers.txt
+ printf %60s | tr ' ' '=' && echo
+ - name: PUT - update database XML resource
+ run: |
+ CHECK=PUT_UPDATE_XML_RESOURCE
+ COLLECTION=example.com/docs
+ RESOURCE=doc-data.xml
+ CHECK_PATH=checks/${CHECK}/${COLLECTION}
+ mkdir -p $CHECK_PATH
+ printf %60s | tr ' ' '=' && echo
+ echo '- Update "document-node" resource'
+ curl --silent --show-error --connect-timeout 1 --max-time 2 \
+ -X PUT \
+ --dump-header ${CHECK_PATH}/headers.txt \
+ --write-out 'response code [ %{http_code} ]\ncontent type [ %{content_type} ]\n' \
+ --header 'Content-Type: application/xml' \
+ --data 'data' \
+ http://localhost:8081/db/${COLLECTION}/${RESOURCE} > ${CHECK_PATH}/write-out.txt
+ printf %60s | tr ' ' '=' && echo
+ echo ' - show headers'
+ echo ' ---------------'
+ cat ${CHECK_PATH}/headers.txt
+ echo && printf %60s | tr ' ' '=' && echo
+ echo ' - show write out'
+ echo ' ----------------'
+ cat ${CHECK_PATH}/write-out.txt && echo
+ printf %60s | tr ' ' '=' && echo
+ echo '- should return "204" status'
+ grep -oP 'HTTP(.+)204(.+)' ${CHECK_PATH}/headers.txt
+ printf %60s | tr ' ' '=' && echo
+ - name: DELETE - remove datebase resource
+ run: |
+ CHECK=DELETE_RESOURCE
+ COLLECTION=example.com/docs
+ RESOURCE=doc-data.xml
+ CHECK_PATH=checks/${CHECK}/${COLLECTION}
+ mkdir -p $CHECK_PATH
+ curl --silent --show-error --connect-timeout 1 --max-time 2 \
+ -X DELETE \
+ --dump-header ${CHECK_PATH}/headers.txt \
+ --write-out 'response code [ %{http_code} ]\ncontent type [ %{content_type} ]\n' \
+ http://localhost:8081/db/${COLLECTION}/${RESOURCE} > ${CHECK_PATH}/write-out.txt
+ printf %60s | tr ' ' '=' && echo
+ echo ' - show headers'
+ echo ' ---------------'
+ cat ${CHECK_PATH}/headers.txt
+ printf %60s | tr ' ' '=' && echo
+ echo ' - show write out'
+ echo ' ----------------'
+ cat ${CHECK_PATH}/write-out.txt
+ echo '- should return "202 Accepted" status'
+ grep -oP 'HTTP(.+)202(.+)' ${CHECK_PATH}/headers.txt
+ printf %60s | tr ' ' '=' && echo
+ - name: HEAD - resource no longer available ( resource has been deleted )
+ run: |
+ CHECK=HEAD_RESOURCE_NOW_UNAVAILABLE
+ COLLECTION=example.com/docs
+ RESOURCE=doc-data.xml
+ CHECK_PATH=checks/${CHECK}/${COLLECTION}
+ mkdir -p $CHECK_PATH
+ curl --silent --show-error --connect-timeout 1 --max-time 2 \
+ -X HEAD \
+ --dump-header ${CHECK_PATH}/headers.txt \
+ --write-out '\nresponse code [ %{http_code} ]\ncontent type [ %{content_type} ]\n' \
+ http://localhost:8081/db/${COLLECTION}/${RESOURCE} > ${CHECK_PATH}/write-out.txt
+ printf %60s | tr ' ' '=' && echo
+ echo ' - show headers'
+ echo ' ---------------'
+ cat ${CHECK_PATH}/headers.txt
+ echo && printf %60s | tr ' ' '=' && echo
+ echo ' - show write out'
+ echo ' ----------------'
+ cat ${CHECK_PATH}/write-out.txt
+ printf %60s | tr ' ' '=' && echo
+ echo '- response should return not found status'
+ grep -oP 'HTTP(.+)404(.+)' ${CHECK_PATH}/headers.txt
+ printf %60s | tr ' ' '=' && echo
+ - name: GET - unavailable resource ( previous resource has been deleted )
+ run: |
+ CHECK=GET_UNAVAILABLE_RESOURCE
+ COLLECTION=example.com/docs
+ RESOURCE=doc-data.xml
+ CHECK_PATH=checks/${CHECK}/${COLLECTION}
+ mkdir -p ${CHECK_PATH}
+ curl --silent --show-error --connect-timeout 1 --max-time 2 \
+ --dump-header ${CHECK_PATH}/headers.txt \
+ --write-out 'response code [ %{http_code} ]\ncontent type [ %{content_type} ]\n' \
+ http://localhost:8081/db/${COLLECTION}/${RESOURCE} > ${CHECK_PATH}/write-out.txt
+ printf %60s | tr ' ' '=' && echo
+ echo ' - show headers'
+ echo ' ---------------'
+ cat ${CHECK_PATH}/headers.txt
+ printf %60s | tr ' ' '=' && echo
+ echo ' - show write out'
+ echo ' ----------------'
+ cat ${CHECK_PATH}/write-out.txt
+ printf %60s | tr ' ' '=' && echo
+ echo '- response should return not found status'
+ grep -oP 'HTTP(.+)404(.+)' ${CHECK_PATH}/headers.txt
+ printf %60s | tr ' ' '=' && echo
+ xqerl_escript_checks:
+ if: ${{ github.ref_type == 'branch' }}
+ needs: build_with_erlang_alpine
+ runs-on: ubuntu-latest
+ timeout-minutes: 10
+ container: erlang:alpine
+ steps:
+ - name: Alpine Deps
+ run: apk add --update grep curl jq
+ - uses: actions/checkout@v3
+ - uses: actions/download-artifact@v3
+ with:
+ name: xqerl-prod-tar
+ - name: Unpack release tar and install xqerl application
+ run: "mkdir /usr/local/xqerl\ntar -zxf xqerl.tar.gz -C /usr/local/xqerl\ncd
+ /usr/local/bin\nln -s /usr/local/xqerl/bin/xqerl\ncd ~/\nxqerl daemon\nsleep
+ 5\nxqerl eval \"file:make_symlink(code:priv_dir(xqerl),\\\"./priv\\\").\"
+ \necho -n ' - set xqerl working directory: '\nxqerl eval \"file:set_cwd('$(pwd)').\"\n"
+ - name: Set Up - add libs and docs
+ run: |
+ printf %60s | tr ' ' '-' && echo
+ xqerl eval "file:make_symlink(code:priv_dir(xqerl),\"./priv\")." | grep -q 'ok'
+ xqerl eval "file:set_cwd('$(pwd)')." | grep -q 'ok'
+ echo ' - compile library module: '
+ xqerl eval 'xqerl:compile("test/restxq/tests.xqm").' &>/dev/null
+ echo ' - db import some XML docs: '
+ xqerl eval 'xqldb_dml:import_from_directory("http://xqerl.org/tests/", "./test/QT3-test-suite/docs").' | grep -q 'ok'
+ xqerl eval 'xqldb_dml:import_from_directory("http://example.com/examples/", "./test/QT3-test-suite/misc").' | grep -q 'ok'
+ - name: Checks - xqerl escript on running instance
+ run: |
+ printf %60s | tr ' ' '-' && echo
+ echo ' - list compiled library modules'
+ echo '> xqerl escript priv/bin/list-libs'
+ xqerl escript priv/bin/list-libs
+ printf %60s | tr ' ' '-' && echo
+ echo ' - list xqerl db contents'
+ echo '> xqerl escript priv/bin/list-db-uri'
+ xqerl escript priv/bin/list-db-uri
+ # - name: Checks - as shebang executable escript
+ # run: |
+ # echo ' - make escript executable'
+ # pushd ~/.local/xqerl/priv/bin/
+ # chmod +x ./list-db-uri
+ # echo ' - now exectable is callable'
+ # echo '> ./list-db-uri'
+ # ./list-db-uri
+ # popd
+ # - name: Checks - as callable executable on PATH
+ # run: |
+ # echo ' - create link to ~/.local/bin'
+ # ln -sf ~/.local/xqerl/priv/bin/list-db-uri ~/.local/bin/xqerl-list-db-uri
+ # echo ' - now exectable is callable from anywhere'
+ # echo '> xqerl-list-db-uri'
+ # xqerl-list-db-uri
diff --git a/.github/workflows/container.yml b/.github/workflows/container.yml
deleted file mode 100644
index 3b1e3d8c..00000000
--- a/.github/workflows/container.yml
+++ /dev/null
@@ -1,115 +0,0 @@
-name: container-images
-on: workflow_dispatch
-jobs:
- build:
- runs-on: ubuntu-latest
- steps:
- - uses: actions/checkout@v3
- - name: Pull Images
- run: |
- XQERL_VERSION=$(grep -oP 'v\d+\.\d+\.\d+' rebar.config)
- # pull in the latest versions of alpine and erlang alpine
- podman pull docker.io/alpine:latest
- ALPINE_VERSION=$(podman run --rm docker.io/alpine:latest /bin/ash -c 'cat /etc/os-release' | grep -oP 'VERSION_ID=\K.+')
- podman pull docker.io/erlang:alpine
- OTP_VERSION=$(podman run --rm docker.io/erlang:alpine sh -c 'cat /usr/local/lib/erlang/releases/*/OTP_VERSION')
- echo " - release version: ${XQERL_VERSION}"
- echo " - uses alpine version: ${ALPINE_VERSION}"
- echo " - uses erlang OTP version: ${OTP_VERSION}"
- - name: Buildah
- run: |
- XQERL_VERSION=$(grep -oP 'v\d+\.\d+\.\d+' rebar.config)
- BASE_CONTAINER=$(buildah from docker.io/erlang:alpine)
- buildah copy ${BASE_CONTAINER} ./ /home/
- buildah run ${BASE_CONTAINER} sh -c 'apk add --update git tar \
- && cd /home \
- && rebar3 as prod tar \
- && mkdir /usr/local/xqerl \
- && tar -zxf _build/prod/rel/xqerl/*.tar.gz -C /usr/local/xqerl'
- CONTAINER=$(buildah from docker.io/alpine:latest)
- buildah run ${CONTAINER} sh -c 'apk add --no-cache openssl ncurses-libs tzdata libstdc++ \
- && mkdir /usr/local/xqerl \
- && cd /usr/local/bin \
- && ln -s /usr/local/xqerl/bin/xqerl'
- buildah copy --from ${BASE_CONTAINER} $CONTAINER /usr/local/xqerl /usr/local/xqerl
- printf %60s | tr ' ' '-' && echo
- echo " - check"
- buildah run ${CONTAINER} sh -c 'which xqerl' # should error if fails to find
- echo " - set working dir and entry point"
- buildah config --cmd '' ${CONTAINER}
- buildah config --workingdir /usr/local/xqerl ${CONTAINER}
- buildah config --entrypoint '[ "xqerl", "foreground"]' ${CONTAINER}
- echo " - set environment vars"
- buildah config --env LANG=C.UTF-8 ${CONTAINER}
- buildah config --env HOME=/home ${CONTAINER}
- buildah config --env XQERL_HOME=/usr/local/xqerl ${CONTAINER}
- printf %60s | tr ' ' '-' && echo
- buildah run ${CONTAINER} sh -c 'printenv' || true
- printf %60s | tr ' ' '-' && echo
- echo " - set stop signal"
- buildah config --stop-signal SIGTERM ${CONTAINER}
- echo " - set labels"
- buildah config --label org.opencontainers.image.base.name=alpine ${CONTAINER}
- buildah config --label org.opencontainers.image.title='xqerl' ${CONTAINER}
- buildah config --label org.opencontainers.image.description='Erlang XQuery 3.1 Processor and XML Database' ${CONTAINER}
- buildah config --label org.opencontainers.image.source=https://github.com/${GITHUB_REPOSITORY} ${CONTAINER} # where the image is built
- buildah config --label org.opencontainers.image.documentation=https://github.com//${GITHUB_REPOSITORY} ${CONTAINER} # image documentation
- buildah config --label org.opencontainers.image.version=${XQERL_VERSION} ${CONTAINER} # version
- buildah run ${CONTAINER} sh -c \
- 'xqerl daemon && sleep 2 && xqerl eval "file:make_symlink(code:priv_dir(xqerl),\"./priv\")." && xqerl stop'
- buildah commit --squash --rm ${CONTAINER} localhost/xqerl
- printf %60s | tr ' ' '-' && echo
- - name: Container Checks
- run: |
- echo " - list docker images"
- podman images
- printf %60s | tr ' ' '-' && echo
- echo " - run container with sh as entrypoint and list working directories"
- podman run --rm --entrypoint '["/bin/sh", "-c"]' localhost/xqerl 'ls -al .'
- echo " - run container with published ports"
- podman run --name xq --publish 8081:8081 --detach localhost/xqerl
- sleep 4
- echo -n ' - check running: '
- podman container inspect -f '{{.State.Running}}' xq
- echo -n ' - check application all started: '
- podman exec xq xqerl eval "application:ensure_all_started(xqerl)." | grep -oP '^.\Kok'
- echo " - check log - only show supervisor"
- printf %60s | tr ' ' '-' && echo
- podman logs -n -t --since 0 -l | grep -oP '^.+\Ksupervisor:.+$'
- printf %60s | tr ' ' '-' && echo
- echo -n ' - check status and running size: '
- podman ps --size --format "{{.Names}} {{.Status}} {{.Size}}"
- echo ' - display the running processes of the container: '
- podman top xq user pid %C
- podman stop xq || true
- - name: Login to GitHub Container Registry
- uses: docker/login-action@v2
- with:
- registry: ghcr.io
- username: ${{ github.actor }}
- password: ${{ secrets.GITHUB_TOKEN }}
- - name: Push to GitHub Container Registry
- run: |
- XQERL_VERSION=$(grep -oP 'v\d+\.\d+\.\d+' rebar.config)
- buildah tag localhost/xqerl ghcr.io/${GITHUB_REPOSITORY}:${XQERL_VERSION}
- buildah push ghcr.io/${GITHUB_REPOSITORY}:${XQERL_VERSION}
- - name: Login to Docker Container Registry
- env:
- DOCKER_TOKEN: ${{ secrets.DOCKER_TOKEN }}
- if: "${{ env.DOCKER_TOKEN != '' }}"
- uses: docker/login-action@v1
- with:
- registry: docker.io
- username: ${{ github.actor }}
- password: ${{ secrets.DOCKER_TOKEN }}
- - name: Push to Docker Container Registry
- env:
- DOCKER_TOKEN: ${{ secrets.DOCKER_TOKEN }}
- if: "${{ env.DOCKER_TOKEN != '' }}"
- run: |
- XQERL_VERSION=$(grep -oP 'v\d+\.\d+\.\d+' rebar.config)
- buildah tag localhost/xqerl docker.io/${GITHUB_REPOSITORY}:${XQERL_VERSION}
- buildah push docker.io/${GITHUB_REPOSITORY}:${XQERL_VERSION}
- buildah tag localhost/xqerl docker.io/${GITHUB_REPOSITORY}:latest
- buildah push docker.io/${GITHUB_REPOSITORY}:latest
-
diff --git a/.github/workflows/feat.yml b/.github/workflows/feat.yml
index 2306742a..8455450b 100644
--- a/.github/workflows/feat.yml
+++ b/.github/workflows/feat.yml
@@ -1,863 +1,25 @@
+# Run on
+# - any pull request
+# - any 'feature' branch except main
+# tasks:
+# build production tar
+# - build_check: builds tar in erlang:alpine container
+# - xqerl_slim: builds tar in erlang:slim container
+# - container_image: on ubuntu-latest pulls erlang:alpine to build tar
+
name: checks on running xqerl instance
on:
pull_request:
- types: [ assigned, opened, synchronize, reopened ]
+ types: [assigned, opened, synchronize, reopened]
push:
branches-ignore:
- main
jobs:
- build:
- runs-on: ubuntu-latest
- timeout-minutes: 30
- steps:
- - name: checkout repo
- uses: actions/checkout@v3
- - name: Cache dependencies
- id: cache-deps
- uses: actions/cache@v2
- with:
- path: _build
- key: rebar-${{ hashFiles('./rebar.lock') }}
- # restore-keys: rebar-
- - name: Cache dependencies
- if: steps.cache-deps.outputs.cache-hit != 'true'
- run: |
- rebar3 deps
- rebar3 compile
- - name: build production tar
- run: |
- rebar3 as prod tar
- mkdir _release
- mv _build/prod/rel/xqerl/*.tar.gz _release/xqerl.tar.gz
- - name: Upload built artifact
- uses: actions/upload-artifact@v3
- with:
- name: xqerl-prod-tar
- path: _release/
- xqerl_eval_checks:
- if: ${{ github.ref_type == 'branch' }}
- needs: build
- runs-on: ubuntu-latest
- timeout-minutes: 5
- steps:
- - name: checkout repo
- uses: actions/checkout@v3
- - name: Download built artifact
- uses: actions/download-artifact@v3
- with:
- name: xqerl-prod-tar
- - name: Unpack release tar and install xqerl application
- run: |
- XQERL_HOME=$HOME/.local/xqerl
- mkdir -p $XQERL_HOME
- mkdir -p $HOME/.local/bin
- tar -zxf xqerl.tar.gz -C $XQERL_HOME
- ln -s $XQERL_HOME/bin/xqerl $HOME/.local/bin
- ls -al $HOME/.local/bin
- echo $PATH
- which xqerl
- - name: Start the xqerl application
- run: |
- xqerl daemon
- sleep 2
- xqerl eval 'application:ensure_all_started(xqerl).'
- - name: Checks - OTP Beam inspection
- run: |
- printf %60s | tr ' ' '-' && echo
- echo -n '- ping: '
- xqerl ping | grep -oP 'pong'
- echo -n '- pid: '
- xqerl pid | grep -oP '\d+'
- printf %60s | tr ' ' '-' && echo
- echo -n ' - set xqerl working directory: '
- xqerl eval "file:set_cwd('$(pwd)')."
- xqerl eval 'file:get_cwd().'
- printf %60s | tr ' ' '=' && echo
- - name: Checks - xqerl eval on running instance
- run: |
- printf %60s | tr ' ' '-' && echo
- echo ' - run a xQuery expression'
- xqerl eval 'xqerl:run("xs:token(\"cats\"), xs:string(\"dogs\"), true() ").' | \
- grep -oP '^\[\{xq.+$'
- printf %60s | tr ' ' '-' && echo
- echo ' - compile an xQuery file'
- xqerl eval 'xqerl:compile("docs/src/sudoku2.xq").' | \
- grep -oP 'file(.+)\.xq'
- printf %60s | tr ' ' '-' && echo
- echo ' - compile, run then grep the title'
- xqerl eval 'S = xqerl:compile("docs/src/sudoku2.xq"),binary_to_list(xqerl_node:to_xml(S:main(#{}))).' | \
- grep -oP '(.+)'
- printf %60s | tr ' ' '-' && echo
- echo -n ' - load an XML file into the DB: '
- xqerl eval \
- 'xqldb_dml:insert_doc("http://xqerl.org/my_doc.xml","./test/QT3-test-suite/app/FunctxFn/functx_order.xml").' | \
- grep -oP 'ok'
- printf %60s | tr ' ' '-' && echo
- echo ' - view using the the xqerl:run/1 function with xQuery fn:doc#1 function'
- xqerl eval "binary_to_list(xqerl:run(\" 'http://xqerl.org/my_doc.xml' => doc() => serialize() \"))."
- printf %60s | tr ' ' '-' && echo
- echo -n ' - delete db doc '
- xqerl eval 'xqldb_dml:delete_doc("http://xqerl.org/my_doc.xml").' | \
- grep -oP 'ok'
- printf %60s | tr ' ' '-' && echo
- echo -n ' - import into DB docs from directory: '
- xqerl eval 'xqldb_dml:import_from_directory("http://xqerl.org/tests/", "./test/QT3-test-suite").' | \
- grep -oP 'ok'
- printf %60s | tr ' ' '=' && echo
- - name: Checks - Features and Issue Resolution
- run: |
- printf %60s | tr ' ' '=' && echo
- printf %60s | tr ' ' '=' && echo
- - name: cowboy static assets handler - issue 46
- run: |
- echo '- use curl to check if image in priv/static/assets dir is reachable'
- printf %60s | tr ' ' '=' && echo
- curl -sSL -D - http://localhost:8081/assets/images/logo.png -o /dev/null
- curl -sSL -D - http://localhost:8081/assets/images/logo.png -o /dev/null | grep -q '200'
- printf %60s | tr ' ' '=' && echo
- - name: after install have a xqerl greeter - issue 48
- run: |
- echo '- use curl to check if http://localhost:8081/xqerl is reachable'
- printf %60s | tr ' ' '=' && echo
- curl -sSL -D - http://localhost:8081/xqerl -o /dev/null
- printf %60s | tr ' ' '=' && echo
- curl -sS http://localhost:8081/xqerl | grep -oP '.+'
- printf %60s | tr ' ' '=' && echo
- - name: maintain builtin routes - issue 66
- run: |
- echo ' - add restXQ route, then check if greeter service still available'
- xqerl eval 'xqerl:compile("test/restxq/tests.xqm").'
- sleep 1
- curl -sSL -D - http://localhost:8081/xqerl -o /dev/null
- curl -sS http://localhost:8081/xqerl | grep -oP '.+'
-
- rest_db_checks:
- if: ${{ github.ref_type == 'branch' }}
- needs: build
- runs-on: ubuntu-latest
- timeout-minutes: 5
- steps:
- - name: checkout repo
- uses: actions/checkout@v3
- - name: Download built artifact
- uses: actions/download-artifact@v3
- with:
- name: xqerl-prod-tar
- - name: Unpack release tar and install xqerl application
- run: |
- XQERL_HOME=$HOME/.local/xqerl
- mkdir -p $XQERL_HOME
- mkdir -p $HOME/.local/bin
- tar -zxf xqerl.tar.gz -C $XQERL_HOME
- ln -s $XQERL_HOME/bin/xqerl $HOME/.local/bin
- - name: Start the xqerl application
- run: |
- xqerl daemon
- sleep 2
- xqerl eval 'application:ensure_all_started(xqerl).'
- - name: POST XML, create XDM document-node resource
- run: |
- CHECK=POST_XML_DATA
- COLLECTION=example.com/docs
- RESOURCE=doc-data.xml
- CHECK_PATH=checks/${CHECK}/${COLLECTION}
- mkdir -p $CHECK_PATH
- curl --silent --show-error --connect-timeout 1 --max-time 2 \
- --dump-header ${CHECK_PATH}/headers.txt \
- --write-out '\nresponse code [ %{http_code} ]\n' \
- --header 'Content-Type: application/xml' \
- --header "Slug: ${RESOURCE}" \
- --data 'data' \
- http://localhost:8081/db/${COLLECTION} > ${CHECK_PATH}/write-out.txt
- printf %60s | tr ' ' '=' && echo
- echo ' - show headers'
- echo ' ---------------'
- cat ${CHECK_PATH}/headers.txt
- printf %60s | tr ' ' '=' && echo
- echo ' - show write out'
- echo ' ----------------'
- cat ${CHECK_PATH}/write-out.txt && echo
- printf %60s | tr ' ' '=' && echo
- echo '- response should return ok created status'
- cat ${CHECK_PATH}/write-out.txt | grep -oP 'response code \[ 201 \]'
- echo '- response headers should include a location header'
- cat ${CHECK_PATH}/headers.txt | grep -oP '^location.+$'
- printf %60s | tr ' ' '='
- - name: POST JSON array create XDM array resource
- run: |
- CHECK=POST_JSON_ARRAY
- COLLECTION=example.com/docs
- RESOURCE=json-data.array
- CHECK_PATH=checks/${CHECK}/${COLLECTION}
- mkdir -p $CHECK_PATH
- curl --silent --show-error --connect-timeout 1 --max-time 2 \
- --dump-header ${CHECK_PATH}/headers.txt \
- --write-out '\nresponse code [ %{http_code} ]\n' \
- --header 'Content-Type: application/json' \
- --header "Slug: ${RESOURCE}" \
- --data '[1,2,3]' \
- http://localhost:8081/db/${COLLECTION} > ${CHECK_PATH}/write-out.txt
- printf %60s | tr ' ' '=' && echo
- echo ' - show headers'
- echo ' ---------------'
- cat ${CHECK_PATH}/headers.txt
- printf %60s | tr ' ' '=' && echo
- echo ' - show write out'
- echo ' ----------------'
- cat ${CHECK_PATH}/write-out.txt && echo
- printf %60s | tr ' ' '=' && echo
- echo '- response should return ok created status'
- grep -q 'response code \[ 201 \]' ${CHECK_PATH}/write-out.txt
- echo '- response headers should include a location header'
- grep -qP '^location.+$' ${CHECK_PATH}/headers.txt
- printf %60s | tr ' ' '='
- - name: POST JSON object create XDM map resource
- run: |
- CHECK=POST_JSON_MAP
- COLLECTION=example.com/docs
- RESOURCE=json-data.map
- CHECK_PATH=checks/${CHECK}/${COLLECTION}
- mkdir -p $CHECK_PATH
- curl --silent --show-error --connect-timeout 1 --max-time 2 \
- --dump-header ${CHECK_PATH}/headers.txt \
- --write-out '\nresponse code [ %{http_code} ]\n' \
- --header 'Content-Type: application/json' \
- --header "Slug: ${RESOURCE}" \
- --data '{"check": "mate"}' \
- http://localhost:8081/db/${COLLECTION} > ${CHECK_PATH}/write-out.txt
- printf %60s | tr ' ' '=' && echo
- echo ' - show headers'
- echo ' ---------------'
- cat ${CHECK_PATH}/headers.txt
- printf %60s | tr ' ' '=' && echo
- echo ' - show write out'
- echo ' ----------------'
- cat ${CHECK_PATH}/write-out.txt
- printf %60s | tr ' ' '=' && echo
- echo '- response should return ok created status'
- grep -q 'response code \[ 201 \]' ${CHECK_PATH}/write-out.txt
- echo '- response headers should include a location header'
- grep -qP '^location.+$' ${CHECK_PATH}/headers.txt
- printf %60s | tr ' ' '='
-
- - name: POST CSV create XDM array resource
- run: |
- CHECK=POST_CSV
- COLLECTION=example.com/docs
- RESOURCE=csv-data.array
- CHECK_PATH=checks/${CHECK}/${COLLECTION}
- mkdir -p $CHECK_PATH
- cat << EOF > $CHECK_PATH/data.csv
- GID,On Street,Species,Trim Cycle,Inventory Date
- 1,ADDISON AV,Celtis australis,Large Tree Routine Prune,10/18/2010
- 2,EMERSON ST,Liquidambar styraciflua,Large Tree Routine Prune,6/2/2010
- EOF
- curl --silent --show-error --connect-timeout 1 --max-time 2 \
- --dump-header ${CHECK_PATH}/headers.txt \
- --write-out '\nresponse code [ %{http_code} ]\n' \
- --header 'Content-Type: text/csv' \
- --header "Slug: ${RESOURCE}" \
- --data-binary "@${CHECK_PATH}/data.csv" \
- http://localhost:8081/db/${COLLECTION} > ${CHECK_PATH}/write-out.txt
- printf %60s | tr ' ' '=' && echo
- echo ' - show headers'
- echo ' ---------------'
- cat ${CHECK_PATH}/headers.txt
- printf %60s | tr ' ' '=' && echo
- echo ' - show write out'
- echo ' ----------------'
- cat ${CHECK_PATH}/write-out.txt
- printf %60s | tr ' ' '=' && echo
- echo '- response should return ok created status'
- grep -q 'response code \[ 201 \]' ${CHECK_PATH}/write-out.txt
- echo '- response headers should include a location header'
- grep -qP '^location.+$' ${CHECK_PATH}/headers.txt
- sleep 1
- printf %60s | tr ' ' '='
-
- - name: POST - unsupported media type
- run: |
- CHECK=POST_MSWORD
- COLLECTION=example.com/docs
- RESOURCE=foo.data
- CHECK_PATH=checks/${CHECK}/${COLLECTION}
- mkdir -p $CHECK_PATH
- curl --silent --show-error --connect-timeout 1 --max-time 2 \
- --dump-header ${CHECK_PATH}/headers.txt \
- --write-out '\nresponse code [ %{http_code} ]\n' \
- --header 'Content-Type: application/msword' \
- --header "Slug: ${RESOURCE}" \
- --data 'foo' \
- http://localhost:8081/db/${COLLECTION} > ${CHECK_PATH}/write-out.txt
- printf %60s | tr ' ' '=' && echo
- echo ' - show headers'
- echo ' ---------------'
- cat ${CHECK_PATH}/headers.txt
- printf %60s | tr ' ' '=' && echo
- echo ' - show write out'
- echo ' ----------------'
- cat ${CHECK_PATH}/write-out.txt
- printf %60s | tr ' ' '=' && echo
- echo '- headers should return "Unsupported Media Type" status'
- grep -qoP 'HTTP(.+)415(.+)' ${CHECK_PATH}/headers.txt
- printf %60s | tr ' ' '=' && echo
- - name: GET - list resources in database collection as text
- run: |
- CHECK=GET_LIST_COLLECTION_RESOURCES_AS_TEXT
- CHECK_PATH=checks/${CHECK}/example.com/docs
- mkdir -p $CHECK_PATH
- curl --silent --show-error --connect-timeout 1 --max-time 2 \
- --header "Accept: text/plain" \
- --dump-header ${CHECK_PATH}/headers.txt \
- --write-out 'response code [ %{http_code} ]\ncontent type [ %{content_type} ]\n' \
- --output ${CHECK_PATH}/output.txt \
- http://localhost:8081/db/example.com/docs > ${CHECK_PATH}/write-out.txt
- echo ' - show headers'
- echo ' ---------------'
- cat ${CHECK_PATH}/headers.txt
- echo '- content-type should be text/plain'
- grep -oP 'content-type: text/plain' ${CHECK_PATH}/headers.txt
- printf %60s | tr ' ' '=' && echo
- echo ' - show write out'
- echo ' ----------------'
- cat ${CHECK_PATH}/write-out.txt && echo
- printf %60s | tr ' ' '=' && echo
- echo ' - show output text'
- echo ' ---------------'
- cat ${CHECK_PATH}/output.txt && echo
- printf %60s | tr ' ' '=' && echo
- echo '- response should return ok created status'
- grep -oP 'response code \[ 200 \]' ${CHECK_PATH}/write-out.txt
- printf %60s | tr ' ' '=' && echo
- - name: GET - list resources in database collection as json
- run: |
- CHECK=GET_LIST_COLLECTION_RESOURCES_AS_JSON
- CHECK_PATH=checks/${CHECK}/example.com/docs
- mkdir -p $CHECK_PATH
- curl --silent --show-error --connect-timeout 1 --max-time 2 \
- --header "Accept: application/json" \
- --dump-header ${CHECK_PATH}/headers.txt \
- --write-out 'response code [ %{http_code} ]\ncontent type [ %{content_type} ]\n' \
- --output ${CHECK_PATH}/output.txt \
- http://localhost:8081/db/example.com/docs > ${CHECK_PATH}/write-out.txt
- echo ' - show headers'
- echo ' ---------------'
- cat ${CHECK_PATH}/headers.txt
- echo '- content-type should be application/json'
- grep -oP 'content-type: application/json' ${CHECK_PATH}/headers.txt
- printf %60s | tr ' ' '=' && echo
- echo ' - show write out'
- echo ' ----------------'
- cat ${CHECK_PATH}/write-out.txt && echo
- printf %60s | tr ' ' '=' && echo
- echo ' - show output as json'
- echo ' ---------------'
- jq '.' ${CHECK_PATH}/output.txt && echo
- printf %60s | tr ' ' '=' && echo
- echo '- response should return ok created status'
- grep -oP 'response code \[ 200 \]' ${CHECK_PATH}/write-out.txt
- printf %60s | tr ' ' '=' && echo
- - name: OPTIONS - allowable methods for collection
- run: |
- CHECK=OPTIONS_COLLECTION
- COLLECTION=example.com/docs
- CHECK_PATH=checks/${CHECK}/${COLLECTION}
- mkdir -p $CHECK_PATH
- curl --silent --show-error --connect-timeout 1 --max-time 2 \
- -X OPTIONS \
- --dump-header ${CHECK_PATH}/headers.txt \
- --write-out 'response code [ %{http_code} ]\ncontent type [ %{content_type} ]' \
- http://localhost:8081/db/${COLLECTION} > ${CHECK_PATH}/write-out.txt
- printf %60s | tr ' ' '=' && echo
- echo ' - show headers'
- echo ' ---------------'
- cat ${CHECK_PATH}/headers.txt
- printf %60s | tr ' ' '=' && echo
- echo ' - show write out'
- echo ' ----------------'
- cat ${CHECK_PATH}/write-out.txt && echo
- printf %60s | tr ' ' '=' && echo
- echo '- headers should return ok status'
- grep -oP 'HTTP(.+)200(.+)' ${CHECK_PATH}/headers.txt
- printf %60s | tr ' ' '=' && echo
- echo '- headers should have allow options'
- grep -oP 'allow:(.+)' ${CHECK_PATH}/headers.txt
- printf %60s | tr ' ' '=' && echo
- - name: HEAD - database collection available accept text
- run: |
- # NOTE: the use of the accept HEADER
- CHECK=HEAD_COLLECTION_AVAILABLE
- COLLECTION=example.com/docs
- CHECK_PATH=checks/${CHECK}/${COLLECTION}
- mkdir -p $CHECK_PATH
- curl --silent --show-error --connect-timeout 1 --max-time 2 \
- --dump-header ${CHECK_PATH}/headers.txt \
- --write-out '\nresponse code [ %{http_code} ]\ncontent type [ %{content_type} ]' \
- --head -H 'Accept: text/plain' \
- http://localhost:8081/db/${COLLECTION} > ${CHECK_PATH}/write-out.txt
- printf %60s | tr ' ' '=' && echo
- echo ' - show headers'
- echo ' ---------------'
- cat ${CHECK_PATH}/headers.txt
- printf %60s | tr ' ' '=' && echo
- echo ' - show write out'
- echo ' ----------------'
- cat ${CHECK_PATH}/write-out.txt && echo
- printf %60s | tr ' ' '=' && echo
- echo '- response should return ok status'
- grep -oP 'response code \[ 200 \]' ${CHECK_PATH}/write-out.txt
- - name: HEAD - database collection available accept xml
- run: |
- # NOTE: the use of the accept HEADER
- CHECK=HEAD_COLLECTION_AVAILABLE
- COLLECTION=example.com/docs
- CHECK_PATH=checks/${CHECK}/${COLLECTION}
- mkdir -p $CHECK_PATH
- curl --silent --show-error --connect-timeout 1 --max-time 2 \
- --dump-header ${CHECK_PATH}/headers.txt \
- --write-out '\nresponse code [ %{http_code} ]\ncontent type [ %{content_type} ]' \
- --head -H 'Accept: application/xml' \
- http://localhost:8081/db/${COLLECTION} > ${CHECK_PATH}/write-out.txt
- printf %60s | tr ' ' '=' && echo
- echo ' - show headers'
- echo ' ---------------'
- cat ${CHECK_PATH}/headers.txt
- printf %60s | tr ' ' '=' && echo
- echo ' - show write out'
- echo ' ----------------'
- cat ${CHECK_PATH}/write-out.txt && echo
- printf %60s | tr ' ' '=' && echo
- echo '- response should return ok status'
- grep -oP 'response code \[ 200 \]' ${CHECK_PATH}/write-out.txt
- - name: HEAD - database resource available
- run: |
- CHECK=HEAD_RESOURCE_AVAILABLE
- COLLECTION=example.com/docs
- RESOURCE=doc-data.xml
- CHECK_PATH=checks/${CHECK}/${COLLECTION}
- mkdir -p $CHECK_PATH
- curl --silent --show-error --connect-timeout 1 --max-time 2 \
- --dump-header ${CHECK_PATH}/headers.txt \
- --write-out '\nresponse code [ %{http_code} ]\ncontent type [ %{content_type} ]\n' \
- --head -H 'Accept: application/xml' \
- http://localhost:8081/db/${COLLECTION}/${RESOURCE} > ${CHECK_PATH}/write-out.txt
- printf %60s | tr ' ' '=' && echo
- echo ' - show headers'
- echo ' ---------------'
- cat ${CHECK_PATH}/headers.txt
- echo && printf %60s | tr ' ' '=' && echo
- echo ' - show write out'
- echo ' ----------------'
- cat ${CHECK_PATH}/write-out.txt
- printf %60s | tr ' ' '=' && echo
- echo '- response should return ok status'
- grep -oP 'response code \[ 200 \]' ${CHECK_PATH}/write-out.txt
- echo ' NOTE; head request can be used to get content size'
- echo ' - header should return content length'
- grep -oP 'content-length(.+)' ${CHECK_PATH}/headers.txt
- if grep -oP 'content-length: 0' ${CHECK_PATH}/headers.txt >/dev/null
- then
- echo ' - header content length should be greater than zero: false'
- false
- else
- echo ' - header content length should be greater than zero: true'
- fi
- printf %60s | tr ' ' '=' && echo
-# NOTE: resource retrieval via Accept Header
- - name: GET - accept XML - retrieve XDM document-node resource
- run: |
- CHECK=GET_ACCEPT_XML
- COLLECTION=example.com/docs
- RESOURCE=doc-data.xml
- CHECK_PATH=checks/${CHECK}/${COLLECTION}
- mkdir -p $CHECK_PATH
- curl --silent --show-error --connect-timeout 1 --max-time 2 \
- --header 'Accept: application/xml' \
- --dump-header ${CHECK_PATH}/headers.txt \
- --write-out 'response code [ %{http_code} ]\ncontent type [ %{content_type} ]\n' \
- --output ${CHECK_PATH}/${RESOURCE} \
- http://localhost:8081/db/${COLLECTION}/${RESOURCE} > ${CHECK_PATH}/write-out.txt
- printf %60s | tr ' ' '=' && echo
- echo ' - show data'
- echo ' ---------------'
- cat ${CHECK_PATH}/${RESOURCE} && echo
- printf %60s | tr ' ' '=' &&
- echo ' - show headers'
- echo ' ---------------'
- cat ${CHECK_PATH}/headers.txt
- echo && printf %60s | tr ' ' '=' && echo
- echo ' - show write out'
- echo ' ----------------'
- cat ${CHECK_PATH}/write-out.txt
- printf %60s | tr ' ' '=' && echo
- echo '- headers should return ok status'
- grep -oP 'HTTP(.+)200(.+)' ${CHECK_PATH}/headers.txt
- printf %60s | tr ' ' '=' && echo
- - name: GET - accept JSON - retrieve XDM array resource
- run: |
- CHECK=GET_ACCEPT_JSON_ARRAY
- COLLECTION=example.com/docs
- RESOURCE=json-data.array
- CHECK_PATH=checks/${CHECK}/${COLLECTION}
- mkdir -p $CHECK_PATH
- curl --silent --show-error --connect-timeout 1 --max-time 2 \
- --header 'Accept: application/json' \
- --dump-header ${CHECK_PATH}/headers.txt \
- --write-out 'response code [ %{http_code} ]\ncontent type [ %{content_type} ]\n' \
- --output ${CHECK_PATH}/${RESOURCE} \
- http://localhost:8081/db/${COLLECTION}/${RESOURCE} > ${CHECK_PATH}/write-out.txt
- printf %60s | tr ' ' '=' && echo
- echo ' - show data'
- echo ' ---------------'
- cat ${CHECK_PATH}/${RESOURCE} && echo
- printf %60s | tr ' ' '=' &&
- echo ' - show headers'
- echo ' ---------------'
- cat ${CHECK_PATH}/headers.txt
- echo && printf %60s | tr ' ' '=' && echo
- echo ' - show write out'
- echo ' ----------------'
- cat ${CHECK_PATH}/write-out.txt
- printf %60s | tr ' ' '=' && echo
- echo '- headers should return ok status'
- grep -oP 'HTTP(.+)200(.+)' ${CHECK_PATH}/headers.txt
- printf %60s | tr ' ' '=' && echo
- - name: GET - accept JSON - retrieve XDM map resource
- run: |
- CHECK=GET_ACCEPT_JSON_MAP
- COLLECTION=example.com/docs
- RESOURCE=json-data.map
- CHECK_PATH=checks/${CHECK}/${COLLECTION}
- mkdir -p $CHECK_PATH
- curl --silent --show-error --connect-timeout 1 --max-time 2 \
- --header 'Accept: application/json' \
- --dump-header ${CHECK_PATH}/headers.txt \
- --write-out 'response code [ %{http_code} ]\ncontent type [ %{content_type} ]\n' \
- --output ${CHECK_PATH}/${RESOURCE} \
- http://localhost:8081/db/${COLLECTION}/${RESOURCE} > ${CHECK_PATH}/write-out.txt
- printf %60s | tr ' ' '=' && echo
- echo ' - show data'
- echo ' ---------------'
- cat ${CHECK_PATH}/${RESOURCE} && echo
- printf %60s | tr ' ' '=' &&
- echo ' - show headers'
- echo ' ---------------'
- cat ${CHECK_PATH}/headers.txt
- echo && printf %60s | tr ' ' '=' && echo
- echo ' - show write out'
- echo ' ----------------'
- cat ${CHECK_PATH}/write-out.txt
- printf %60s | tr ' ' '=' && echo
- echo '- headers should return ok status'
- grep -oP 'HTTP(.+)200(.+)' ${CHECK_PATH}/headers.txt
- printf %60s | tr ' ' '=' && echo
-
- - name: GET - tabular data - ask for JSON, origin posted CSV data
- run: |
- CHECK=CHECK=GET_ACCEPT_JSON_TABULAR_DATA
- COLLECTION=example.com/docs
- RESOURCE=csv-data.array
- CHECK_PATH=checks/${CHECK}/${COLLECTION}
- mkdir -p $CHECK_PATH
- curl --silent --show-error --connect-timeout 1 --max-time 2 \
- --header 'Accept: application/json' \
- --dump-header ${CHECK_PATH}/headers.txt \
- --write-out 'response code [ %{http_code} ]\ncontent type [ %{content_type} ]\n' \
- --output ${CHECK_PATH}/${RESOURCE} \
- http://localhost:8081/db/${COLLECTION}/${RESOURCE} > ${CHECK_PATH}/write-out.txt
- printf %60s | tr ' ' '=' && echo
- echo ' - show data'
- echo ' ---------------'
- jq '.' ${CHECK_PATH}/${RESOURCE}
- printf %60s | tr ' ' '=' &&
- echo ' - show headers'
- echo ' ---------------'
- cat ${CHECK_PATH}/headers.txt
- echo && printf %60s | tr ' ' '=' && echo
- echo ' - show write out'
- echo ' ----------------'
- cat ${CHECK_PATH}/write-out.txt
- printf %60s | tr ' ' '=' && echo
- echo '- headers should return ok status'
- grep -oP 'HTTP(.+)200(.+)' ${CHECK_PATH}/headers.txt
- printf %60s | tr ' ' '=' && echo
-
- - name: GET - tabular data metadata - ask for JSON, origin posted CSV data
- run: |
- CHECK=GET_ACCEPT_JSON_TABULAR_METADATA
- COLLECTION=example.com/docs
- RESOURCE=csv-data.array-metadata.json
- CHECK_PATH=checks/${CHECK}/${COLLECTION}
- mkdir -p $CHECK_PATH
- curl --silent --show-error --connect-timeout 1 --max-time 2 \
- --header 'Accept: application/json' \
- --dump-header ${CHECK_PATH}/headers.txt \
- --write-out 'response code [ %{http_code} ]\ncontent type [ %{content_type} ]\n' \
- --output ${CHECK_PATH}/${RESOURCE} \
- http://localhost:8081/db/${COLLECTION}/${RESOURCE} > ${CHECK_PATH}/write-out.txt
- printf %60s | tr ' ' '=' && echo
- echo ' - show data'
- echo ' ---------------'
- jq '.' ${CHECK_PATH}/${RESOURCE}
- printf %60s | tr ' ' '=' && echo
- echo ' - show headers'
- echo ' ---------------'
- cat ${CHECK_PATH}/headers.txt
- echo && printf %60s | tr ' ' '=' && echo
- echo ' - show write out'
- echo ' ----------------'
- cat ${CHECK_PATH}/write-out.txt
- printf %60s | tr ' ' '=' && echo
- echo '- headers should return ok status'
- grep -oP 'HTTP(.+)200(.+)' ${CHECK_PATH}/headers.txt
- printf %60s | tr ' ' '=' && echo
-
- - name: GET - tabular data - ask for HTML, origin posted CSV data
- run: |
- CHECK=CHECK=GET_ACCEPT_HTML_TABULAR_DATA
- COLLECTION=example.com/docs
- RESOURCE=csv-data.array
- CHECK_PATH=checks/${CHECK}/${COLLECTION}
- mkdir -p $CHECK_PATH
- curl --silent --show-error --connect-timeout 1 --max-time 2 \
- --header 'Accept: text/html' \
- --dump-header ${CHECK_PATH}/headers.txt \
- --write-out 'response code [ %{http_code} ]\ncontent type [ %{content_type} ]\n' \
- --output ${CHECK_PATH}/${RESOURCE} \
- http://localhost:8081/db/${COLLECTION}/${RESOURCE} > ${CHECK_PATH}/write-out.txt
- printf %60s | tr ' ' '=' && echo
- echo ' - show data'
- echo ' ---------------'
- cat ${CHECK_PATH}/${RESOURCE}
- echo && printf %60s | tr ' ' '=' &&
- echo ' - show headers'
- echo ' ---------------'
- cat ${CHECK_PATH}/headers.txt
- echo && printf %60s | tr ' ' '=' && echo
- echo ' - show write out'
- echo ' ----------------'
- cat ${CHECK_PATH}/write-out.txt
- printf %60s | tr ' ' '=' && echo
- echo '- headers should return ok status'
- grep -oP 'HTTP(.+)200(.+)' ${CHECK_PATH}/headers.txt
- printf %60s | tr ' ' '=' && echo
-
- - name: GET - tabular data - ask for CSV text, origin posted CSV data
- run: |
- CHECK=CHECK=GET_ACCEPT_CSV_TABULAR_DATA
- COLLECTION=example.com/docs
- RESOURCE=csv-data.array
- CHECK_PATH=checks/${CHECK}/${COLLECTION}
- mkdir -p $CHECK_PATH
- curl --silent --show-error --connect-timeout 1 --max-time 2 \
- --header 'Accept: text/csv' \
- --dump-header ${CHECK_PATH}/headers.txt \
- --write-out 'response code [ %{http_code} ]\ncontent type [ %{content_type} ]\n' \
- --output ${CHECK_PATH}/${RESOURCE} \
- http://localhost:8081/db/${COLLECTION}/${RESOURCE} > ${CHECK_PATH}/write-out.txt
- printf %60s | tr ' ' '=' && echo
- echo ' - show data'
- echo ' ---------------'
- cat ${CHECK_PATH}/${RESOURCE}
- echo && printf %60s | tr ' ' '=' &&
- echo ' - show headers'
- echo ' ---------------'
- cat ${CHECK_PATH}/headers.txt
- echo && printf %60s | tr ' ' '=' && echo
- echo ' - show write out'
- echo ' ----------------'
- cat ${CHECK_PATH}/write-out.txt
- printf %60s | tr ' ' '=' && echo
- echo '- headers should return ok status'
- grep -oP 'HTTP(.+)200(.+)' ${CHECK_PATH}/headers.txt
- printf %60s | tr ' ' '=' && echo
-
-
-
-
- - name: GET - unknown resource in collection
- run: |
- CHECK=GET_UKNOWN_RESOURCE
- COLLECTION=example.com/docs
- RESOURCE=erewhon.xml
- CHECK_PATH=checks/${CHECK}/${COLLECTION}
- mkdir -p $CHECK_PATH
- curl --silent --show-error --connect-timeout 1 --max-time 2 \
- --dump-header ${CHECK_PATH}/headers.txt \
- --write-out 'response code [ %{http_code} ]\ncontent type [ %{content_type} ]\n' \
- http://localhost:8081/db/${COLLECTION}/${RESOURCE} > ${CHECK_PATH}/write-out.txt
- printf %60s | tr ' ' '=' &&
- echo ' - show headers'
- echo ' ---------------'
- cat ${CHECK_PATH}/headers.txt
- echo && printf %60s | tr ' ' '=' && echo
- echo ' - show write out'
- echo ' ----------------'
- cat ${CHECK_PATH}/write-out.txt
- printf %60s | tr ' ' '=' && echo
- echo '- headers should return not found status'
- grep -oP 'HTTP(.+)404(.+)' ${CHECK_PATH}/headers.txt
- printf %60s | tr ' ' '=' && echo
- - name: PUT - update database XML resource
- run: |
- CHECK=PUT_UPDATE_XML_RESOURCE
- COLLECTION=example.com/docs
- RESOURCE=doc-data.xml
- CHECK_PATH=checks/${CHECK}/${COLLECTION}
- mkdir -p $CHECK_PATH
- printf %60s | tr ' ' '=' && echo
- echo '- Update "document-node" resource'
- curl --silent --show-error --connect-timeout 1 --max-time 2 \
- -X PUT \
- --dump-header ${CHECK_PATH}/headers.txt \
- --write-out 'response code [ %{http_code} ]\ncontent type [ %{content_type} ]\n' \
- --header 'Content-Type: application/xml' \
- --data 'data' \
- http://localhost:8081/db/${COLLECTION}/${RESOURCE} > ${CHECK_PATH}/write-out.txt
- printf %60s | tr ' ' '=' && echo
- echo ' - show headers'
- echo ' ---------------'
- cat ${CHECK_PATH}/headers.txt
- echo && printf %60s | tr ' ' '=' && echo
- echo ' - show write out'
- echo ' ----------------'
- cat ${CHECK_PATH}/write-out.txt && echo
- printf %60s | tr ' ' '=' && echo
- echo '- should return "204" status'
- grep -oP 'HTTP(.+)204(.+)' ${CHECK_PATH}/headers.txt
- printf %60s | tr ' ' '=' && echo
- - name: DELETE - remove datebase resource
- run: |
- CHECK=DELETE_RESOURCE
- COLLECTION=example.com/docs
- RESOURCE=doc-data.xml
- CHECK_PATH=checks/${CHECK}/${COLLECTION}
- mkdir -p $CHECK_PATH
- curl --silent --show-error --connect-timeout 1 --max-time 2 \
- -X DELETE \
- --dump-header ${CHECK_PATH}/headers.txt \
- --write-out 'response code [ %{http_code} ]\ncontent type [ %{content_type} ]\n' \
- http://localhost:8081/db/${COLLECTION}/${RESOURCE} > ${CHECK_PATH}/write-out.txt
- printf %60s | tr ' ' '=' && echo
- echo ' - show headers'
- echo ' ---------------'
- cat ${CHECK_PATH}/headers.txt
- printf %60s | tr ' ' '=' && echo
- echo ' - show write out'
- echo ' ----------------'
- cat ${CHECK_PATH}/write-out.txt
- echo '- should return "202 Accepted" status'
- grep -oP 'HTTP(.+)202(.+)' ${CHECK_PATH}/headers.txt
- printf %60s | tr ' ' '=' && echo
- - name: HEAD - resource no longer available ( resource has been deleted )
- run: |
- CHECK=HEAD_RESOURCE_NOW_UNAVAILABLE
- COLLECTION=example.com/docs
- RESOURCE=doc-data.xml
- CHECK_PATH=checks/${CHECK}/${COLLECTION}
- mkdir -p $CHECK_PATH
- curl --silent --show-error --connect-timeout 1 --max-time 2 \
- -X HEAD \
- --dump-header ${CHECK_PATH}/headers.txt \
- --write-out '\nresponse code [ %{http_code} ]\ncontent type [ %{content_type} ]\n' \
- http://localhost:8081/db/${COLLECTION}/${RESOURCE} > ${CHECK_PATH}/write-out.txt
- printf %60s | tr ' ' '=' && echo
- echo ' - show headers'
- echo ' ---------------'
- cat ${CHECK_PATH}/headers.txt
- echo && printf %60s | tr ' ' '=' && echo
- echo ' - show write out'
- echo ' ----------------'
- cat ${CHECK_PATH}/write-out.txt
- printf %60s | tr ' ' '=' && echo
- echo '- response should return not found status'
- grep -oP 'HTTP(.+)404(.+)' ${CHECK_PATH}/headers.txt
- printf %60s | tr ' ' '=' && echo
- - name: GET - unavailable resource ( previous resource has been deleted )
- run: |
- CHECK=GET_UNAVAILABLE_RESOURCE
- COLLECTION=example.com/docs
- RESOURCE=doc-data.xml
- CHECK_PATH=checks/${CHECK}/${COLLECTION}
- mkdir -p ${CHECK_PATH}
- curl --silent --show-error --connect-timeout 1 --max-time 2 \
- --dump-header ${CHECK_PATH}/headers.txt \
- --write-out 'response code [ %{http_code} ]\ncontent type [ %{content_type} ]\n' \
- http://localhost:8081/db/${COLLECTION}/${RESOURCE} > ${CHECK_PATH}/write-out.txt
- printf %60s | tr ' ' '=' && echo
- echo ' - show headers'
- echo ' ---------------'
- cat ${CHECK_PATH}/headers.txt
- printf %60s | tr ' ' '=' && echo
- echo ' - show write out'
- echo ' ----------------'
- cat ${CHECK_PATH}/write-out.txt
- printf %60s | tr ' ' '=' && echo
- echo '- response should return not found status'
- grep -oP 'HTTP(.+)404(.+)' ${CHECK_PATH}/headers.txt
- printf %60s | tr ' ' '=' && echo
- - name: Stop xqerl
- run: xqerl stop
-
- xqerl_escript_checks:
- if: ${{ github.ref_type == 'branch' }}
- needs: build
- runs-on: ubuntu-latest
- timeout-minutes: 5
- steps:
- - name: checkout repo
- uses: actions/checkout@v3
- - name: Download built artifact
- uses: actions/download-artifact@v3
- with:
- name: xqerl-prod-tar
- - name: Unpack release tar and install xqerl application
- run: |
- XQERL_HOME=$HOME/.local/xqerl
- mkdir -p $XQERL_HOME
- mkdir -p $HOME/.local/bin
- tar -zxf xqerl.tar.gz -C $XQERL_HOME
- ln -s $XQERL_HOME/bin/xqerl $HOME/.local/bin
- - name: Start the xqerl application
- run: |
- xqerl daemon
- sleep 2
- xqerl eval 'application:ensure_all_started(xqerl).'
- - name: Set Up - add libs and docs
- run: |
- printf %60s | tr ' ' '-' && echo
- xqerl eval "file:make_symlink(code:priv_dir(xqerl),\"./priv\")." | grep -q 'ok'
- xqerl eval "file:set_cwd('$(pwd)')." | grep -q 'ok'
- echo ' - compile library module: '
- xqerl eval 'xqerl:compile("test/restxq/tests.xqm").' &>/dev/null
- echo ' - db import some XML docs: '
- xqerl eval 'xqldb_dml:import_from_directory("http://xqerl.org/tests/", "./test/QT3-test-suite/docs").' | grep -q 'ok'
- xqerl eval 'xqldb_dml:import_from_directory("http://example.com/examples/", "./test/QT3-test-suite/misc").' | grep -q 'ok'
- - name: Checks - xqerl escript on running instance
- run: |
- printf %60s | tr ' ' '-' && echo
- echo ' - list compiled library modules'
- echo '> xqerl escript priv/bin/list-libs'
- xqerl escript priv/bin/list-libs
- printf %60s | tr ' ' '-' && echo
- echo ' - list xqerl db contents'
- echo '> xqerl escript priv/bin/list-db-uri'
- xqerl escript priv/bin/list-db-uri
- - name: Checks - as shebang executable escript
- run: |
- echo ' - make escript executable'
- pushd ~/.local/xqerl/priv/bin/
- chmod +x ./list-db-uri
- echo ' - now exectable is callable'
- echo '> ./list-db-uri'
- ./list-db-uri
- popd
- - name: Checks - as callable executable on PATH
- run: |
- echo ' - create link to ~/.local/bin'
- ln -sf ~/.local/xqerl/priv/bin/list-db-uri ~/.local/bin/xqerl-list-db-uri
- echo ' - now exectable is callable from anywhere'
- echo '> xqerl-list-db-uri'
- xqerl-list-db-uri
- - name: stop xqerl
- run: xqerl stop
+ build_check:
+ uses: ./.github/workflows/build-check.yml
+ xqerl_slim:
+ needs: build_check
+ uses: ./.github/workflows/xqerl-slim-tar.yml
+ container-image:
+ #needs: build_check
+ uses: ./.github/workflows/xqerl-alpine-image.yml
diff --git a/.github/workflows/xqerl-alpine-image.yml b/.github/workflows/xqerl-alpine-image.yml
new file mode 100644
index 00000000..898df313
--- /dev/null
+++ b/.github/workflows/xqerl-alpine-image.yml
@@ -0,0 +1,908 @@
+# job: container_image_build
+# - builds minimal alpine based image to run xqerl app server and database instances
+# - produces the image saved as a upload-artifact
+#
+# In subsequent 'jobs' a download-artifact 'xqerl.tar'
+# is loaded into the local container registry and
+# a running xqerl instance is created and checks
+# are performed
+# - db_ops_crud_with_curl:
+# - Check working with xqerl rest db api to Create Retrieve Update and Delete db resources
+# - Check stoping and starting container instance can retain db application state via a xqerl database volume
+# - Check saving xqerl-database volume as a tar
+# - bulk_db ops_xml
+
+name: xqerl alpine container image
+on:
+ workflow_call:
+jobs:
+ container_image_build:
+ runs-on: ubuntu-latest
+ timeout-minutes: 10
+ env:
+ DOCKER_TOKEN: ${{ secrets.DOCKER_TOKEN }}
+ steps:
+ - uses: actions/checkout@v3
+ - name: Pull Images
+ run: |
+ XQERL_VERSION=$(grep -oP 'v\d+\.\d+\.\d+' rebar.config)
+ podman pull docker.io/erlang:alpine &>/dev/null
+ OTP_VERSION=$(podman run --rm docker.io/erlang:alpine sh -c 'cat /usr/local/lib/erlang/releases/*/OTP_VERSION')
+ ALPINE_VERSION=$(podman run --rm docker.io/erlang:alpine sh -c 'cat /etc/os-release' | grep -oP 'VERSION_ID=\K.+')
+ podman pull docker.io/alpine:$ALPINE_VERSION
+ echo '# xqerl container image ' >> $GITHUB_STEP_SUMMARY
+ echo " - xqerl release version: ${XQERL_VERSION}" >> $GITHUB_STEP_SUMMARY
+ echo " - uses erlang OTP version: ${OTP_VERSION}" >> $GITHUB_STEP_SUMMARY
+ echo " - uses alpine version: ${ALPINE_VERSION}" >> $GITHUB_STEP_SUMMARY
+
+ - name: Buildah
+ run: |
+ echo " ## container image build" >> $GITHUB_STEP_SUMMARY
+ XQERL_VERSION=$(grep -oP 'v\d+\.\d+\.\d+' rebar.config)
+ BASE_CONTAINER=$(buildah from docker.io/erlang:alpine)
+ buildah copy ${BASE_CONTAINER} ./ /home/
+ buildah run ${BASE_CONTAINER} sh -c 'apk add --update git tar \
+ && cd /home \
+ && rebar3 as prod tar &>/dev/null \
+ && mkdir /usr/local/xqerl \
+ && tar -zxf _build/prod/rel/xqerl/*.tar.gz -C /usr/local/xqerl \
+ && cd /usr/local/xqerl \
+ && bin/xqerl daemon \
+ && sleep 4 \
+ && bin/xqerl eval "file:make_symlink(code:priv_dir(xqerl),\"./priv\")." \
+ && bin/xqerl stop \
+ && ls -al .'
+ ALPINE_VERSION=$(podman run --rm docker.io/erlang:alpine sh -c 'cat /etc/os-release' | grep -oP 'VERSION_ID=\K.+')
+ CONTAINER=$(buildah from docker.io/alpine:$ALPINE_VERSION)
+ buildah run ${CONTAINER} sh -c 'apk add --no-cache openssl ncurses-libs tzdata libstdc++ \
+ && mkdir /usr/local/xqerl \
+ && cd /usr/local/bin \
+ && ln -s /usr/local/xqerl/bin/xqerl'
+ buildah copy --from ${BASE_CONTAINER} $CONTAINER /usr/local/xqerl /usr/local/xqerl
+ echo -n " - check xqerl on PATH: "
+ buildah run ${CONTAINER} sh -c 'which xqerl' # should error if fails to find
+ echo " - set working dir and entry point and stop signal" >> $GITHUB_STEP_SUMMARY
+ buildah config \
+ --cmd '' \
+ --workingdir /usr/local/xqerl \
+ --entrypoint '[ "xqerl", "foreground"]' \
+ --stop-signal SIGTERM ${CONTAINER}
+ echo " - set environment vars" >> $GITHUB_STEP_SUMMARY
+ buildah config \
+ --env LANG=C.UTF-8 \
+ --env HOME=/home \
+ --env XQERL_HOME=/usr/local/xqerl ${CONTAINER}
+ printf %60s | tr ' ' '-' && echo
+ buildah run ${CONTAINER} sh -c 'printenv' || true
+ printf %60s | tr ' ' '-' && echo
+ echo " - set labels" >> $GITHUB_STEP_SUMMARY
+ buildah config \
+ --label org.opencontainers.image.base.name=alpine \
+ --label org.opencontainers.image.title='xqerl' \
+ --label org.opencontainers.image.description='Erlang XQuery 3.1 Processor and XML Database' \
+ --label org.opencontainers.image.source=https://github.com/${GITHUB_REPOSITORY} \
+ --label org.opencontainers.image.documentation=https://github.com//${GITHUB_REPOSITORY} \
+ --label org.opencontainers.image.version=${XQERL_VERSION} ${CONTAINER}
+ echo " - commited squashed container image " >> $GITHUB_STEP_SUMMARY
+ buildah commit --squash --rm ${CONTAINER} localhost/xqerl
+ printf %60s | tr ' ' '-' && echo
+ podman save --quiet -o xqerl.tar localhost/xqerl
+ podman rmi localhost/xqerl
+ - name: Upload artifact
+ uses: actions/upload-artifact@v3
+ with:
+ name: xqerl-image
+ path: xqerl.tar
+
+ db_ops_crud_with_curl:
+ if: ${{ github.ref_type == 'branch' }}
+ needs: container_image_build
+ runs-on: ubuntu-latest
+ timeout-minutes: 10
+ steps:
+ - uses: actions/checkout@v3
+ - uses: actions/download-artifact@v3
+ with:
+ name: xqerl-image
+ - name: Load image
+ run: |
+ echo " ## Running Container Instance " >> $GITHUB_STEP_SUMMARY
+ podman load --input xqerl.tar
+ podman images
+ printf %60s | tr ' ' '-' && echo
+ echo " - [x] load an image archive into container storage" >> $GITHUB_STEP_SUMMARY
+ - name: Run Container Instance
+ run: |
+ echo " - [x] run container with sh as entrypoint and list working directories" >> $GITHUB_STEP_SUMMARY
+ podman run --rm --entrypoint '["/bin/sh", "-c"]' localhost/xqerl 'ls -al .'
+ # echo " - timezone: $(timedatectl | grep -oP 'Time zone: \K[\w/]+')"
+ podman volume exists xqerl-code || podman volume create xqerl-code
+ podman volume exists xqerl-database || podman volume create xqerl-database
+ podman volume exists xqerl-priv || podman volume create xqerl-priv
+ podman run --name xq --publish 8081:8081 \
+ --mount type=volume,target=/usr/local/xqerl/code,source=xqerl-code \
+ --mount type=volume,target=/usr/local/xqerl/data,source=xqerl-database \
+ --mount type=volume,target=/usr/local/xqerl/priv,source=xqerl-priv \
+ --tz=$(timedatectl | grep -oP 'Time zone: \K[\w/]+') \
+ --detach localhost/xqerl
+ sleep 2
+ # crash check
+ ! podman logs xq | grep -oP 'CRASH REPORT' &>/dev/null
+ echo -n ' - check status and running size: '
+ podman ps --size --format "{{.Names}} {{.Status}} {{.Size}}"
+ echo ' - display the running processes of the container: '
+ podman top xq user pid %C
+ echo " - [x] run xqerl application as a detached container" >> $GITHUB_STEP_SUMMARY
+ echo " - container named: xq" >> $GITHUB_STEP_SUMMARY
+ echo " - container port: 8081" >> $GITHUB_STEP_SUMMARY
+ echo " - container timezone set at runtime" >> $GITHUB_STEP_SUMMARY
+
+ - name: POST XML, create XDM document-node resource with SLUG
+ run: |
+ echo "### Checking: Create Retrieve Update, Delete db ops with Curl" >> $GITHUB_STEP_SUMMARY
+ CHECK=POST_XML_DATA
+ COLLECTION=example.com/docs
+ RESOURCE=doc-data.xml
+ CHECK_PATH=checks/${CHECK}/${COLLECTION}
+ mkdir -p $CHECK_PATH
+ echo 'data' |
+ curl --silent --show-error --connect-timeout 2 --max-time 4 \
+ --dump-header ${CHECK_PATH}/headers.txt \
+ --write-out '\nresponse code [ %{http_code} ]\n' \
+ --header 'Content-Type: application/xml' \
+ --header "Slug: ${RESOURCE}" \
+ --data-binary @- \
+ http://localhost:8081/db/${COLLECTION} > ${CHECK_PATH}/write-out.txt
+ printf %60s | tr ' ' '=' && echo
+ # show results in actions
+ echo ' - show headers'
+ echo ' ---------------'
+ cat ${CHECK_PATH}/headers.txt
+ printf %60s | tr ' ' '=' && echo
+ echo ' - show write out'
+ echo ' ----------------'
+ cat ${CHECK_PATH}/write-out.txt && echo
+ printf %60s | tr ' ' '=' && echo
+ # success failure checks - failure aborts run
+ echo '- response should return ok created status'
+ cat ${CHECK_PATH}/write-out.txt | grep -oP 'response code \[ 201 \]'
+ echo '- response headers should include a location header'
+ cat ${CHECK_PATH}/headers.txt | grep -oP '^location.+$'
+ printf %60s | tr ' ' '=' && echo
+ - name: POST XML, create another XDM document-node resource with SLUG
+ run: |
+ CHECK=POST_XML_DATA
+ COLLECTION=example.com/docs
+ RESOURCE=doc-more-data.xml
+ CHECK_PATH=checks/${CHECK}/${COLLECTION}
+ mkdir -p $CHECK_PATH
+ echo 'more data' |
+ curl --silent --show-error --connect-timeout 2 --max-time 4 \
+ --dump-header ${CHECK_PATH}/headers.txt \
+ --write-out '\nresponse code [ %{http_code} ]\n' \
+ --header 'Content-Type: application/xml' \
+ --header "Slug: ${RESOURCE}" \
+ --data-binary @- \
+ http://localhost:8081/db/${COLLECTION} > ${CHECK_PATH}/write-out.txt
+ printf %60s | tr ' ' '=' && echo
+ # show results in actions
+ echo ' - show headers'
+ echo ' ---------------'
+ cat ${CHECK_PATH}/headers.txt
+ printf %60s | tr ' ' '=' && echo
+ echo ' - show write out'
+ echo ' ----------------'
+ cat ${CHECK_PATH}/write-out.txt && echo
+ printf %60s | tr ' ' '=' && echo
+ # success failure checks - failure aborts run
+ echo '- response should return ok created status'
+ cat ${CHECK_PATH}/write-out.txt | grep -oP 'response code \[ 201 \]'
+ echo '- response headers should include a location header'
+ cat ${CHECK_PATH}/headers.txt | grep -oP '^location.+$'
+ printf %60s | tr ' ' '=' && echo
+ echo " - [x] POST request with SLUG header creates stored db XDM item \
+ and return Created status and a Loction header" >> $GITHUB_STEP_SUMMARY
+ - name: POST XML, create XDM document-node resource without slug
+ run: |
+ CHECK=POST_XML_DATA
+ COLLECTION=example.com/docs
+ RESOURCE=doc-data.xml
+ CHECK_PATH=checks/${CHECK}/${COLLECTION}
+ mkdir -p $CHECK_PATH
+ echo 'data' |
+ curl --silent --show-error --connect-timeout 1 --max-time 2 \
+ --dump-header ${CHECK_PATH}/headers.txt \
+ --write-out '\nresponse code [ %{http_code} ]\n' \
+ --header 'Content-Type: application/xml' \
+ --data-binary @- \
+ http://localhost:8081/db/${COLLECTION} > ${CHECK_PATH}/write-out.txt
+ printf %60s | tr ' ' '=' && echo
+ # show results in actions
+ echo ' - show headers'
+ echo ' ---------------'
+ cat ${CHECK_PATH}/headers.txt
+ printf %60s | tr ' ' '=' && echo
+ echo ' - show write out'
+ echo ' ----------------'
+ cat ${CHECK_PATH}/write-out.txt && echo
+ printf %60s | tr ' ' '=' && echo
+ # success failure checks - failure aborts run
+ echo '- response should return ok created status'
+ cat ${CHECK_PATH}/write-out.txt | grep -oP 'response code \[ 201 \]'
+ echo '- response headers should include a location header'
+ cat ${CHECK_PATH}/headers.txt | grep -oP '^location.+$'
+ printf %60s | tr ' ' '=' && echo
+ echo " - [x] POST request without SLUG header creates stored db XDM item" >> $GITHUB_STEP_SUMMARY
+
+ - name: HEAD - database resource available
+ run: |
+ CHECK=HEAD_RESOURCE_AVAILABLE
+ COLLECTION=example.com/docs
+ RESOURCE=doc-data.xml
+ CHECK_PATH=checks/${CHECK}/${COLLECTION}
+ mkdir -p $CHECK_PATH
+ curl --silent --show-error --connect-timeout 1 --max-time 2 \
+ --dump-header ${CHECK_PATH}/headers.txt \
+ --write-out '\nresponse code [ %{http_code} ]\ncontent type [ %{content_type} ]\n' \
+ --head -H 'Accept: application/xml' \
+ http://localhost:8081/db/${COLLECTION}/${RESOURCE} > ${CHECK_PATH}/write-out.txt
+ printf %60s | tr ' ' '=' && echo
+ echo ' - show headers'
+ echo ' ---------------'
+ cat ${CHECK_PATH}/headers.txt
+ echo && printf %60s | tr ' ' '=' && echo
+ echo ' - show write out'
+ echo ' ----------------'
+ cat ${CHECK_PATH}/write-out.txt
+ printf %60s | tr ' ' '=' && echo
+ echo '- response should return ok status'
+ grep -oP 'response code \[ 200 \]' ${CHECK_PATH}/write-out.txt
+ echo ' NOTE; head request can be used to get content size'
+ echo ' - header should return content length'
+ grep -oP 'content-length(.+)' ${CHECK_PATH}/headers.txt
+ if grep -oP 'content-length: 0' ${CHECK_PATH}/headers.txt >/dev/null
+ then
+ echo ' - header content length should be greater than zero: false'
+ false
+ else
+ echo ' - header content length should be greater than zero: true'
+ fi
+ printf %60s | tr ' ' '=' && echo
+ echo " - [x] HEAD request can detirmine document availablity" >> $GITHUB_STEP_SUMMARY
+ echo " - [x] HEAD request can be used to get the resource content size" >> $GITHUB_STEP_SUMMARY
+
+ - name: GET - accept XML - retrieve XDM document-node resource
+ run: |
+ CHECK=GET_ACCEPT_XML
+ COLLECTION=example.com/docs
+ RESOURCE=doc-data.xml
+ CHECK_PATH=checks/${CHECK}/${COLLECTION}
+ mkdir -p $CHECK_PATH
+ curl --silent --show-error --connect-timeout 1 --max-time 2 \
+ --header 'Accept: application/xml' \
+ --dump-header ${CHECK_PATH}/headers.txt \
+ --write-out 'response code [ %{http_code} ]\ncontent type [ %{content_type} ]\n' \
+ --output ${CHECK_PATH}/${RESOURCE} \
+ http://localhost:8081/db/${COLLECTION}/${RESOURCE} > ${CHECK_PATH}/write-out.txt
+ printf %60s | tr ' ' '=' && echo
+ echo ' - show data'
+ echo ' ---------------'
+ cat ${CHECK_PATH}/${RESOURCE} && echo
+ printf %60s | tr ' ' '=' &&
+ echo ' - show headers'
+ echo ' ---------------'
+ cat ${CHECK_PATH}/headers.txt
+ echo && printf %60s | tr ' ' '=' && echo
+ echo ' - show write out'
+ echo ' ----------------'
+ cat ${CHECK_PATH}/write-out.txt
+ printf %60s | tr ' ' '=' && echo
+ echo '- headers should return ok status'
+ grep -oP 'HTTP(.+)200(.+)' ${CHECK_PATH}/headers.txt
+ printf %60s | tr ' ' '=' && echo
+ echo ' - [x] GET request with accept "application/xml" header retrieves serialized XML document' >> $GITHUB_STEP_SUMMARY
+ - name: PUT - update database XML resource
+ run: |
+ CHECK=PUT_UPDATE_XML_RESOURCE
+ COLLECTION=example.com/docs
+ RESOURCE=doc-data.xml
+ CHECK_PATH=checks/${CHECK}/${COLLECTION}
+ mkdir -p $CHECK_PATH
+ printf %60s | tr ' ' '=' && echo
+ echo '- Update "document-node" resource'
+ echo 'datum' |
+ curl --silent --show-error --connect-timeout 1 --max-time 2 \
+ -X PUT \
+ --dump-header ${CHECK_PATH}/headers.txt \
+ --write-out 'response code [ %{http_code} ]\ncontent type [ %{content_type} ]\n' \
+ --header 'Content-Type: application/xml' \
+ --data-binary @- \
+ http://localhost:8081/db/${COLLECTION}/${RESOURCE} > ${CHECK_PATH}/write-out.txt
+ printf %60s | tr ' ' '=' && echo
+ echo ' - show headers'
+ echo ' ---------------'
+ cat ${CHECK_PATH}/headers.txt
+ echo && printf %60s | tr ' ' '=' && echo
+ echo ' - show write out'
+ echo ' ----------------'
+ cat ${CHECK_PATH}/write-out.txt && echo
+ printf %60s | tr ' ' '=' && echo
+ echo '- should return "204" status'
+ grep -oP 'HTTP(.+)204(.+)' ${CHECK_PATH}/headers.txt
+ printf %60s | tr ' ' '=' && echo
+ echo ' - [x] PUT request with Content-Type "application/xml" header stores XDM item into db' >> $GITHUB_STEP_SUMMARY
+
+ - name: GET after PUT - accept XML - retrieve XDM document-node resource
+ run: |
+ CHECK=GET_ACCEPT_XML
+ COLLECTION=example.com/docs
+ RESOURCE=doc-data.xml
+ CHECK_PATH=checks/${CHECK}/${COLLECTION}
+ mkdir -p $CHECK_PATH
+ curl --silent --show-error --connect-timeout 1 --max-time 2 \
+ --header 'Accept: application/xml' \
+ --dump-header ${CHECK_PATH}/headers.txt \
+ --write-out 'response code [ %{http_code} ]\ncontent type [ %{content_type} ]\n' \
+ --output ${CHECK_PATH}/${RESOURCE} \
+ http://localhost:8081/db/${COLLECTION}/${RESOURCE} > ${CHECK_PATH}/write-out.txt
+ printf %60s | tr ' ' '=' && echo
+ echo ' - show data'
+ echo ' ---------------'
+ cat ${CHECK_PATH}/${RESOURCE} && echo
+ printf %60s | tr ' ' '=' &&
+ echo ' - show headers'
+ echo ' ---------------'
+ cat ${CHECK_PATH}/headers.txt
+ echo && printf %60s | tr ' ' '=' && echo
+ echo ' - show write out'
+ echo ' ----------------'
+ cat ${CHECK_PATH}/write-out.txt
+ printf %60s | tr ' ' '=' && echo
+ echo '- headers should return ok status'
+ grep -oP 'HTTP(.+)200(.+)' ${CHECK_PATH}/headers.txt
+ printf %60s | tr ' ' '=' && echo
+ echo ' - [x] GET request after PUT to retrieve stored resource' >> $GITHUB_STEP_SUMMARY
+
+ - name: DELETE - remove database resource
+ run: |
+ CHECK=DELETE_RESOURCE
+ COLLECTION=example.com/docs
+ RESOURCE=doc-more-data.xml
+ CHECK_PATH=checks/${CHECK}/${COLLECTION}
+ mkdir -p $CHECK_PATH
+ curl --silent --show-error --connect-timeout 1 --max-time 2 \
+ -X DELETE \
+ --dump-header ${CHECK_PATH}/headers.txt \
+ --write-out 'response code [ %{http_code} ]\ncontent type [ %{content_type} ]\n' \
+ http://localhost:8081/db/${COLLECTION}/${RESOURCE} > ${CHECK_PATH}/write-out.txt
+ printf %60s | tr ' ' '=' && echo
+ echo ' - show headers'
+ echo ' ---------------'
+ cat ${CHECK_PATH}/headers.txt
+ printf %60s | tr ' ' '=' && echo
+ echo ' - show write out'
+ echo ' ----------------'
+ cat ${CHECK_PATH}/write-out.txt
+ echo '- should return "202 Accepted" status'
+ grep -oP 'HTTP(.+)202(.+)' ${CHECK_PATH}/headers.txt
+ printf %60s | tr ' ' '=' && echo
+ echo ' - [x] DELETE request deletes a stored db item' >> $GITHUB_STEP_SUMMARY
+ podman exec xq xqerl escript priv/bin/list-db-uri
+
+ - name: Container pause unpause check
+ run: |
+ echo '### Maintaining application state after restarts' >> $GITHUB_STEP_SUMMARY
+ podman pause xq
+ sleep 2
+ podman ps -a
+ sleep 2
+ podman unpause xq
+ sleep 2
+ podman ps -a
+ sleep 2
+ podman top xq
+ sleep 2
+ podman logs xq | grep -A 2 'application: xqerl'
+ podman logs xq | grep -A 3 'xqldb_path_table,start_link'
+ # podman logs xq | sed -n -e '/application: xqerl/,$p'
+ #podman logs --tail 300 xq | grep -oP 'http://example.com/docs/'
+ printf %60s | tr ' ' '-' && echo
+ CHECK=GET_ACCEPT_XML
+ COLLECTION=example.com/docs
+ RESOURCE=doc-data.xml
+ CHECK_PATH=checks/${CHECK}/${COLLECTION}
+ mkdir -p $CHECK_PATH
+ curl --silent --show-error --connect-timeout 1 --max-time 2 \
+ --header 'Accept: application/xml' \
+ --dump-header ${CHECK_PATH}/headers.txt \
+ --write-out 'response code [ %{http_code} ]\ncontent type [ %{content_type} ]\n' \
+ --output ${CHECK_PATH}/${RESOURCE} \
+ http://localhost:8081/db/${COLLECTION}/${RESOURCE} > ${CHECK_PATH}/write-out.txt
+ printf %60s | tr ' ' '=' && echo
+ echo ' - show data'
+ echo ' ---------------'
+ cat ${CHECK_PATH}/${RESOURCE} && echo
+ printf %60s | tr ' ' '=' &&
+ echo ' - show headers'
+ echo ' ---------------'
+ cat ${CHECK_PATH}/headers.txt
+ echo && printf %60s | tr ' ' '=' && echo
+ echo ' - show write out'
+ echo ' ----------------'
+ cat ${CHECK_PATH}/write-out.txt
+ printf %60s | tr ' ' '=' && echo
+ echo '- headers should return ok status'
+ grep -oP 'HTTP(.+)200(.+)' ${CHECK_PATH}/headers.txt
+ printf %60s | tr ' ' '=' && echo
+ echo ' - [x] after container paused and then unpaused previous \
+ stored db items are still available and retrievable' >> $GITHUB_STEP_SUMMARY
+ - name: Stop and remove container, run new instance
+ run: |
+ podman stop xq && podman rm xq && podman ps -a
+ podman run --name xq --publish 8081:8081 \
+ --mount type=volume,target=/usr/local/xqerl/code,source=xqerl-code \
+ --mount type=volume,target=/usr/local/xqerl/data,source=xqerl-database \
+ --mount type=volume,target=/usr/local/xqerl/priv,source=xqerl-priv \
+ --mount type=bind,target=/home,source=./test \
+ --tz=$(timedatectl | grep -oP 'Time zone: \K[\w/]+') \
+ --detach localhost/xqerl
+ sleep 1 && echo -n ' - check running: '
+ podman container inspect -f '{{.State.Running}}' xq
+ sleep 1 && podman ps -a
+ sleep 1 && podman top xq
+ sleep 1 && podman logs xq | grep -A 2 'application: xqerl'
+ printf %60s | tr ' ' '-' && echo
+ echo ' - [x] Container can be stopped and removed' >> $GITHUB_STEP_SUMMARY
+ echo ' - [x] When a new container instance is run with the mounted volumes, \
+ the stored db items are still available and retrievable' >> $GITHUB_STEP_SUMMARY
+ - name: check - after new instance run list data items in the xqerl-database volume
+ run: |
+ ITEM_COUNT=$(podman exec xq xqerl escript priv/bin/list-db-uri | wc -l)
+ echo " database items: $ITEM_COUNT"
+ [ $ITEM_COUNT -gt 0 ]
+ echo " database item list"
+ podman exec xq xqerl escript priv/bin/list-db-uri
+ echo && printf %60s | tr ' ' '=' && echo
+
+ - name: Backup xqerl database application state
+ run: |
+ echo ' - stop the xqerl application running processes'
+ podman pause xq
+ echo " - export 'xqerl-database' volume which contains the xqerl database application state"
+ podman volume export xqerl-database --output xqerl-database-volume.tar
+ echo ' - start the xqerl application running processes'
+ podman unpause xq
+ echo && printf %60s | tr ' ' '=' && echo
+ # the tarball is uploaded
+ - name: Upload artifact
+ uses: actions/upload-artifact@v3
+ with:
+ name: xqerl-database-volume
+ path: xqerl-database-volume.tar
+
+ restoring_data_from_tarball:
+ if: ${{ github.ref_type == 'branch' }}
+ needs: db_ops_crud_with_curl
+ runs-on: ubuntu-latest
+ timeout-minutes: 5
+ steps:
+ - uses: actions/checkout@v3
+ - uses: actions/download-artifact@v3
+ - id: load_image_run_container
+ run: |
+ # create volumes if they don't exist
+ podman volume exists xqerl-code || podman volume create xqerl-code
+ podman volume exists xqerl-database || podman volume create xqerl-database
+ podman volume exists xqerl-priv || podman volume create xqerl-priv
+ # Import tarball contents into an existing podman volume
+ cat xqerl-database-volume/xqerl-database-volume.tar | podman volume import xqerl-database -
+ # Load localhost/xqerl image into container registry
+ cat xqerl-image/xqerl.tar | podman load
+ podman run --name xq --publish 8081:8081 \
+ --mount type=volume,target=/usr/local/xqerl/code,source=xqerl-code \
+ --mount type=volume,target=/usr/local/xqerl/data,source=xqerl-database \
+ --mount type=volume,target=/usr/local/xqerl/priv,source=xqerl-priv \
+ --tz=$(timedatectl | grep -oP 'Time zone: \K[\w/]+') \
+ --detach localhost/xqerl
+ echo -n ' - check running: '
+ sleep 2 && podman container inspect -f '{{.State.Running}}' xq
+ podman ps -a && sleep 2 && podman top xq
+ sleep 2
+ # the database should be restored
+ ITEM_COUNT=$(podman exec xq xqerl escript priv/bin/list-db-uri | wc -l)
+ echo " database items: $ITEM_COUNT"
+ [ $ITEM_COUNT -gt 0 ]
+ echo " database item list"
+ podman exec xq xqerl escript priv/bin/list-db-uri
+ echo && printf %60s | tr ' ' '=' && echo
+ echo ' - [x] xqerl-database volume can archived as backup tarball snapshot' >> $GITHUB_STEP_SUMMARY
+ echo ' - [x] the archive can be merged into a volume to restore data' >> $GITHUB_STEP_SUMMARY
+
+#
+#
+ bulk_db_ops_xml:
+ if: ${{ github.ref_type == 'branch' }}
+ needs: container_image_build
+ runs-on: ubuntu-latest
+ timeout-minutes: 10
+ steps:
+ - uses: actions/checkout@v3
+ - uses: actions/download-artifact@v3
+ with:
+ name: xqerl-image
+ - id: load_image_run_container
+ run: |
+ podman load --input xqerl.tar
+ podman volume exists xqerl-code || podman volume create xqerl-code
+ podman volume exists xqerl-database || podman volume create xqerl-database
+ podman volume exists xqerl-priv || podman volume create xqerl-priv
+ podman run --name xq --publish 8081:8081 \
+ --mount type=volume,target=/usr/local/xqerl/code,source=xqerl-code \
+ --mount type=volume,target=/usr/local/xqerl/data,source=xqerl-database \
+ --mount type=volume,target=/usr/local/xqerl/priv,source=xqerl-priv \
+ --mount type=bind,target=/home,source=./test \
+ --tz=$(timedatectl | grep -oP 'Time zone: \K[\w/]+') \
+ --detach localhost/xqerl
+ echo -n ' - check running: '
+ sleep 2 && podman container inspect -f '{{.State.Running}}' xq
+ podman ps -a && sleep 2 && podman top xq
+ sleep 2
+ podman exec xq sh -c 'ls -al /home'
+ podman exec xq xqerl eval $'{ok, CurrentDirectory} = file:get_cwd().'
+#####################################
+# xqerl function - xqldb_dml:import from directory
+# XML files in test dir
+####################################
+ - name: xqldb_dml import from directory
+ run: |
+ echo -n ' - import from directory: '
+ podman exec xq xqerl eval 'xqldb_dml:import_from_directory("http://example.com/QT3-test-suit/docs/", "/home/QT3-test-suite/docs").'
+ # echo ' - [x] bulk load with built in function xqldb_dml:import_from_directory#2' >> $GITHUB_STEP_SUMMARY
+ # echo ' - checks: retrieve docs starting with letter b using built in function doc#1'
+ # mkdir -p checks
+ # find test/QT3-test-suite/docs -name "b*.xml" -type f | awk '{ system("sleep 1"); print $1 }' |
+ # xargs -l bash -c $'podman exec xq xqerl eval \'xqerl:run("doc(\'http://example.com/QT3-test-suit/docs/$(basename $0)\')").\''
+ # use built in function db:get#1
+ # echo ' - checks: retrieve docs starting with letter b using xqerl function db:get#1'
+ # find test/QT3-test-suite/docs -name "b*.xml" -type f | awk '{ system("sleep 1"); print $1 }' |
+ # xargs -l bash -c "DIRNAME=$(dirname $0);BASENAME=$(basename $0); echo && \
+ # podman exec xq xqerl eval \"xerl:run(\"db:get('http://example.com/QT3-test-suit/docs/$BASENAME') => serialize()\").\""
+ # podman exec xq xqerl escript priv/bin/list-db-uri
+ # # podman exec xq xqerl escript priv/bin/list-db-uri "http://example.com/QT3-test-suit/docs"
+ # echo ' - check for duplicate db items: '
+ # podman exec xq xqerl escript priv/bin/list-db-uri | uniq --repeated
+ # podman exec xq xqerl escript priv/bin/list-db-uri | uniq --count --repeated
+ # ITEM_COUNT_1=$(podman exec xq xqerl escript priv/bin/list-db-uri | wc -l)
+ # podman pause xq && podman unpause xq && sleep 1 # stop and start running processes in container
+ # ITEM_COUNT_2=$(podman exec xq xqerl escript priv/bin/list-db-uri | wc -l)
+ # [ $ITEM_COUNT_1 -eq $ITEM_COUNT_2 ]
+ - name: DB check - duplicate items
+ run: |
+ if [ $( podman exec xq xqerl escript priv/bin/list-db-uri | uniq --count --repeated | wc -l ) -gt 0 ]
+ then
+ echo -e "\e[31mWarning:\e[0m duplicate db uri"
+ podman exec xq xqerl escript priv/bin/list-db-uri | uniq -cd
+ echo -e ' - [ ] list-db-uri displays no duplicate resource uri identifiers' >> $GITHUB_STEP_SUMMARY
+ else
+ echo ' - [x] list-db-uri displays no duplicate resource uri identifiers'
+ fi
+
+ - name: DB ops - delete
+ run: |
+ mkdir -p checks
+ touch checks/deleted-xml.txt
+ # delete docs starting with letter b
+ find test/QT3-test-suite/docs -name "b*.xml" -type f | awk '{ system("sleep 1"); print $1 }' |
+ xargs -l bash -c 'DIRNAME=$(dirname $0);BASENAME=$(basename $0); \
+ echo && curl --silent --show-error --connect-timeout 1 --max-time 2 \
+ -X DELETE \
+ --dump-header /dev/null \
+ --write-out \
+ "response code [ %{response_code} ]\nDELETE URL [ %{url_effective} ]" \
+ http://localhost:8081/db/example.com/QT3-test-suit/docs/$BASENAME && echo' >> checks/deleted-xml.txt
+ cat checks/deleted-xml.txt
+ podman exec xq xqerl escript priv/bin/list-db-uri
+ # try to delete duplicate
+ echo "" > checks/deleted-xml.txt
+ find test/QT3-test-suite/docs/higher-order -name "*.xml" -type f | awk '{ system("sleep 1"); print $1 }' |
+ xargs -l bash -c 'DIRNAME=$(dirname $0);BASENAME=$(basename $0); \
+ echo && curl --silent --show-error --connect-timeout 1 --max-time 2 \
+ -X DELETE \
+ --dump-header /dev/null \
+ --write-out \
+ "response code [ %{response_code} ]\nDELETE URL [ %{url_effective} ]" \
+ http://localhost:8081/db/example.com/QT3-test-suit/docs/$BASENAME && echo' >> checks/deleted-xml.txt
+ cat checks/deleted-xml.txt
+ podman exec xq xqerl escript priv/bin/list-db-uri
+
+ - name: DB ops - update
+ run: |
+ mkdir -p checks
+ touch checks/update-xml.txt
+ # put docs starting with letter a
+ find test/QT3-test-suite/docs -name "a*.xml" -type f | awk '{ system("sleep 1"); print $1 }' |
+ xargs -l bash -c 'DIRNAME=$(dirname $0);BASENAME=$(basename $0); \
+ echo && cat $0 | \
+ curl --silent --show-error --connect-timeout 1 --max-time 2 \
+ -X PUT \
+ --dump-header /dev/null \
+ --write-out \
+ "\nPUT URL [ %{url_effective} ]\nresponse code [ %{response_code} ]\nsize upload [ %{size_upload} ]\ntime total[ %{time_total} ]" \
+ --header "Content-Type: application/xml" \
+ --data-binary @- http://localhost:8081/db/example.com/QT3-test-suit/docs/$BASENAME && echo' >> checks/update-xml.txt
+ cat checks/update-xml.txt
+ podman exec xq xqerl escript priv/bin/list-db-uri
+
+ - name: Container database reset one
+ run: |
+ podman stop xq && podman rm xq && podman ps -a
+ # destroy then recreate database
+ podman volume rm xqerl-database
+ podman volume create xqerl-database
+ podman run --name xq --publish 8081:8081 \
+ --mount type=volume,target=/usr/local/xqerl/code,source=xqerl-code \
+ --mount type=volume,target=/usr/local/xqerl/data,source=xqerl-database \
+ --mount type=volume,target=/usr/local/xqerl/priv,source=xqerl-priv \
+ --tz=$(timedatectl | grep -oP 'Time zone: \K[\w/]+') \
+ --detach localhost/xqerl
+ sleep 2
+ echo -n ' - check running: '
+ podman container inspect -f '{{.State.Running}}' xq
+ podman logs xq | grep -A 2 'application: xqerl' || true
+ podman logs xq | sed -n -e '/application: xqerl/,$p' || true
+ podman top xq
+ echo ' - [x] reset database application state via volume removal and creation' >> $GITHUB_STEP_SUMMARY
+# #####################################
+# # rest db API
+# # bulk load XML files in test dir files into db with Curl
+# ####################################
+ - name: DB ops - rest db API - bulk load XML files into db with Curl
+ run: |
+ mkdir -p checks
+ touch checks/posted-xml.txt
+ echo '- load XML files from ./test/QT3-test-suite/docs into db'
+ find test/QT3-test-suite/docs -name "*.xml" -type f | awk '{ system("sleep 1"); print $1 }' |
+ xargs -l bash -c 'DIRNAME=$(dirname $0);BASENAME=$(basename $0); \
+ echo && echo "Filename as Slug: $BASENAME" && \
+ cat $0 | \
+ curl --silent --show-error --connect-timeout 2 --max-time 4 \
+ --write-out \
+ "\nSlug: $BASENAME\nPOST URL [ %{url_effective} ]\nresponse code [ %{response_code} ]\nsize upload [ %{size_upload} ]\ntime total[ %{time_total} ]" \
+ --header "Content-Type: application/xml" \
+ --header "Slug: $BASENAME" \
+ --data-binary @- http://localhost:8081/db/example.com/$DIRNAME && echo' | tee -a checks/posted-xml.txt
+ - name: checks - rest db API - after bulk loading XML files into db
+ run: |
+ if [ $( podman exec xq xqerl escript priv/bin/list-db-uri | uniq --count --repeated | wc -l ) -gt 0 ]
+ then
+ echo ' - [ ] list-db-uri displays no duplicate resource uri identifiers' >> $GITHUB_STEP_SUMMARY
+ podman exec xq xqerl escript priv/bin/list-db-uri | uniq -cd
+ fi
+ podman stop xq && podman rm xq && podman ps -a
+ podman run --name xq --publish 8081:8081 \
+ --mount type=volume,target=/usr/local/xqerl/code,source=xqerl-code \
+ --mount type=volume,target=/usr/local/xqerl/data,source=xqerl-database \
+ --mount type=volume,target=/usr/local/xqerl/priv,source=xqerl-priv \
+ --tz=$(timedatectl | grep -oP 'Time zone: \K[\w/]+') \
+ --detach localhost/xqerl
+ sleep 2
+ echo -n ' - check running: '
+ podman container inspect -f '{{.State.Running}}' xq
+ podman ps -a && sleep 2 && podman top xq
+ echo ' - [x] bulk load XML files into db with Curl' >> $GITHUB_STEP_SUMMARY
+#
+ bulk_db_ops_json:
+ if: ${{ github.ref_type == 'branch' }}
+ needs: container_image_build
+ runs-on: ubuntu-latest
+ timeout-minutes: 10
+ steps:
+ - uses: actions/checkout@v3
+ - uses: actions/download-artifact@v3
+ with:
+ name: xqerl-image
+ - id: load_image_run_container
+ run: |
+ podman load --input xqerl.tar
+ podman volume exists xqerl-code || podman volume create xqerl-code
+ podman volume exists xqerl-database || podman volume create xqerl-database
+ podman volume exists xqerl-priv || podman volume create xqerl-priv
+ podman run --name xq --publish 8081:8081 \
+ --mount type=volume,target=/usr/local/xqerl/code,source=xqerl-code \
+ --mount type=volume,target=/usr/local/xqerl/data,source=xqerl-database \
+ --mount type=volume,target=/usr/local/xqerl/priv,source=xqerl-priv \
+ --tz=$(timedatectl | grep -oP 'Time zone: \K[\w/]+') \
+ --detach localhost/xqerl
+ echo -n ' - check running: '
+ sleep 2 && podman container inspect -f '{{.State.Running}}' xq
+ podman ps -a && sleep 2 && podman top xq
+ sleep 2
+ podman exec xq sh -c 'ls -al /home'
+ podman exec xq xqerl eval $'{ok, CurrentDirectory} = file:get_cwd().'
+#####################################
+# JSON files in test dir
+# Note some of these files are not single well formed JSON files
+# so should produce a 400 Bad Request
+# However {}{} is considered valid json
+# test if valid json
+# `jq empty` file.json
+#####################################
+ # - name: DB ops - rest db API - bulk POSTing of json files with Curl
+ # run: |
+ # echo '## DB ops - bulk POSTing of json files with Curl' >> $GITHUB_STEP_SUMMARY
+ # mkdir -p checks
+ # touch checks/posted-json.txt
+ # echo ' - load JSON files from ./test/QT3-test-suite/app into db' | tee -a checks/posted-json.txt
+ # echo ' - Note some of these files are not well formed and ' | tee -a checks/posted-json.txt
+ # echo ' will produce a 400 Bad Request' | tee -a checks/posted-json.txt
+ # find test/QT3-test-suite/app -name "*.json" -type f | awk '{ system("sleep 1"); print $1 }' |
+ # xargs -l bash -c 'DIRNAME=$(dirname $0);BASENAME=$(basename $0); \
+ # echo && cat $0 | \
+ # curl --silent --show-error --connect-timeout 2 --max-time 4 \
+ # --write-out \
+ # "\nSlug: $BASENAME\nPOST URL [ %{url_effective} ]\nresponse code [ %{response_code} ]\nsize upload [ %{size_upload} ]\ntime total[ %{time_total} ]" \
+ # --header "Content-Type: application/json" \
+ # --header "Slug: $BASENAME" \
+ # --data-binary @- http://localhost:8081/db/example.com/$DIRNAME && echo' >> checks/posted-json.txt
+ # printf %60s | tr ' ' '=' && echo
+
+ JSONTestSuite:
+ if: ${{ github.ref_type == 'branch' }}
+ needs: container_image_build
+ runs-on: ubuntu-latest
+ timeout-minutes: 10
+ steps:
+ - uses: actions/checkout@v3
+ - uses: actions/download-artifact@v3
+ with:
+ name: xqerl-image
+ - id: load_image_run_container
+ run: |
+ echo '## JSON test suite compliance' >> $GITHUB_STEP_SUMMARY
+ podman load --input xqerl.tar
+ podman volume exists xqerl-code || podman volume create xqerl-code
+ podman volume exists xqerl-database || podman volume create xqerl-database
+ podman volume exists xqerl-priv || podman volume create xqerl-priv
+ podman run --name xq --publish 8081:8081 \
+ --mount type=volume,target=/usr/local/xqerl/code,source=xqerl-code \
+ --mount type=volume,target=/usr/local/xqerl/data,source=xqerl-database \
+ --mount type=volume,target=/usr/local/xqerl/priv,source=xqerl-priv \
+ --tz=$(timedatectl | grep -oP 'Time zone: \K[\w/]+') \
+ --detach localhost/xqerl
+ echo -n ' - check running: '
+ sleep 2 && podman container inspect -f '{{.State.Running}}' xq
+ podman ps -a && sleep 2 && podman top xq
+ podman exec xq xqerl eval $'{ok, CurrentDirectory} = file:get_cwd().'
+ - name: DB ops - POST files from JSONTestSuite -y prefix
+ run: |
+ echo '### DB ops - POST files from JSONTestSuite with letter y prefix' >> $GITHUB_STEP_SUMMARY
+ mkdir -p checks
+ echo ' - load y prefix JSON files from ./test/QT3-test-suite/misc/JSONTestSuite into db' > checks/yPrefixJSONTestSuite.txt
+ echo ' - files prefixed with y_ MUST be accepted by parsers' >> checks/yPrefixJSONTestSuite.txt
+ echo ' - so all should load into db with a 201 Created response' >> checks/yPrefixJSONTestSuite.txt
+ find test/QT3-test-suite/misc/JSONTestSuite -name "y_*" -type f | awk '{ system("sleep 1"); print $1 }' |
+ xargs -l bash -c 'DIRNAME=$(dirname $0);BASENAME=$(basename $0); \
+ echo && cat $0 | \
+ curl --silent --show-error --connect-timeout 2 --max-time 4 \
+ --write-out \
+ "response code [ %{response_code} ]\nSlug: $BASENAME\nPOST URL [ %{url_effective} ]\nsize upload [ %{size_upload} ]\ntime total[ %{time_total} ]" \
+ --header "Content-Type: application/json" \
+ --header "Slug: $BASENAME" \
+ --data-binary @- http://localhost:8081/db/example.com/$DIRNAME && echo' >> checks/yPrefixJSONTestSuite.txt
+ printf %60s | tr ' ' '=' && echo
+ echo ' - check for duplicate db items: '
+ podman exec xq xqerl escript priv/bin/list-db-uri | uniq -cd || true
+ echo " - items that SHOULD be loaded into db: \
+ $(find test/QT3-test-suite/misc/JSONTestSuite -name 'y_*' -type f | wc -l)" >> $GITHUB_STEP_SUMMARY
+ if [ $(grep -oP '^response code...400' checks/yPrefixJSONTestSuite.txt | wc -l) -gt 0 ]
+ then
+ echo " - [ ] posted items NOT loaded into db $(grep -oP '^response code...400' checks/yPrefixJSONTestSuite.txt | wc -l)" >> $GITHUB_STEP_SUMMARY
+ echo ' - show items that SHOULD be parsed'
+ grep -P -A 4 '^response code...400' checks/yPrefixJSONTestSuite.txt
+ fi
+ echo " - [x] db items created: $(grep -oP '^response code...201' checks/yPrefixJSONTestSuite.txt | wc -l)" >> $GITHUB_STEP_SUMMARY
+
+ - name: DB ops - POST files from JSONTestSuite with letter i prefix
+ run: |
+ echo '### DB ops - POST files from JSONTestSuite with letter i prefix' >> $GITHUB_STEP_SUMMARY
+ mkdir -p checks
+ echo ' - load JSON files from ./test/QT3-test-suite/misc/JSONTestSuite into db' | tee checks/iPrefixJSONTestSuite.txt
+ echo ' - these are the files prefixed with i_.' | tee -a checks/iPrefixJSONTestSuite.txt
+ echo ' - i_ parsers are free to accept or reject content, so only some should load into db ' | tee -a checks/iPrefixJSONTestSuite.txt
+ find test/QT3-test-suite/misc/JSONTestSuite -name "i_*" -type f | awk '{ system("sleep 1"); print $1 }' |
+ xargs -l bash -c 'DIRNAME=$(dirname $0);BASENAME=$(basename $0); \
+ echo && cat $0 | \
+ curl --silent --show-error --connect-timeout 2 --max-time 4 \
+ --write-out \
+ "response code [ %{response_code} ]\nSlug: $BASENAME\nPOST URL [ %{url_effective} ]\nsize upload [ %{size_upload} ]\ntime total[ %{time_total} ]" \
+ --header "Content-Type: application/json" \
+ --header "Slug: $BASENAME" \
+ --data-binary @- http://localhost:8081/db/example.com/$DIRNAME && echo' >> checks/iPrefixJSONTestSuite.txt
+ printf %60s | tr ' ' '=' && echo
+ # echo ' - check for duplicate db items: '
+ # podman exec xq xqerl escript priv/bin/list-db-uri | uniq -cd
+ echo " - items that MAY be loaded into db: $(find test/QT3-test-suite/misc/JSONTestSuite -name 'i_*' -type f | wc -l)" >> $GITHUB_STEP_SUMMARY
+ echo " - [x] db items created: $(grep -oP '^response code...201' checks/iPrefixJSONTestSuite.txt | wc -l)" >> $GITHUB_STEP_SUMMARY
+ echo " - [x] posted items NOT loaded into db: $(grep -oP '^response code...400' checks/iPrefixJSONTestSuite.txt | wc -l) " >> $GITHUB_STEP_SUMMARY
+
+ - name: DB ops - POST files from JSONTestSuite with letter n prefix
+ run: |
+ echo '### DB ops - POST files from JSONTestSuite with letter n prefix' >> $GITHUB_STEP_SUMMARY
+ mkdir -p checks
+ echo ' - load JSON files from ./test/QT3-test-suite/misc/JSONTestSuite into db' | tee checks/nPrefixJSONTestSuite.txt
+ find test/QT3-test-suite/misc/JSONTestSuite -name "n_*" -type f | awk '{ system("sleep 1"); print $1 }' |
+ xargs -l bash -c 'DIRNAME=$(dirname $0);BASENAME=$(basename $0); \
+ echo && cat $0 | \
+ curl --silent --show-error --connect-timeout 2 --max-time 4 \
+ --write-out \
+ "response code [ %{response_code} ]\nSlug: $BASENAME\nPOST URL [ %{url_effective} ]\nsize upload [ %{size_upload} ]\ntime total[ %{time_total} ]" \
+ --header "Content-Type: application/json" \
+ --header "Slug: $BASENAME" \
+ --data-binary @- http://localhost:8081/db/example.com/$DIRNAME && echo' >> checks/nPrefixJSONTestSuite.txt
+ echo " - items that SHOULD NOT loaded into db: $(find test/QT3-test-suite/misc/JSONTestSuite -name 'i_*' -type f | wc -l)" >> $GITHUB_STEP_SUMMARY
+ echo -n ' - items that SHOULD NOT be loaded: '
+ find test/QT3-test-suite/misc/JSONTestSuite -name "n_*" -type f | wc -l
+ echo -n ' - db items created: '
+ grep -oP '^response code...201' checks/nPrefixJSONTestSuite.txt | wc -l || true
+ echo -n ' - posted items NOT loaded into db: '
+ grep -oP '^response code...400' checks/nPrefixJSONTestSuite.txt | wc -l || true
+ if [ $(grep -oP '^response code...201' checks/nPrefixJSONTestSuite.txt | wc -l) -gt 0 ]
+ then
+ echo " - [ ] db items created: $(grep -oP '^response code...201' checks/iPrefixJSONTestSuite.txt | wc -l)" >> $GITHUB_STEP_SUMMARY
+ echo ' - show items that SHOULD NOT be parsed'
+ grep -P -A 4 '^response code...201' checks/nPrefixJSONTestSuite.txt
+ fi
+ echo " - [x] posted items NOT loaded into db: $(grep -oP '^response code...400' checks/iPrefixJSONTestSuite.txt | wc -l) " >> $GITHUB_STEP_SUMMARY
+#
+# - name: DB check - duplicate items
+# run: |
+# echo -n ' - check for duplicate db items: '
+# podman exec xq xqerl escript priv/bin/list-db-uri | uniq -cd | wc -l
+ # podman exec xq xqerl escript priv/bin/list-db-uri | uniq --repeated
+ # podman exec xq xqerl escript priv/bin/list-db-uri | uniq --count --repeated
+
+
+ container_image_release:
+ if: ${{ github.ref_type == 'tag' }}
+ needs: container_image_build
+ runs-on: ubuntu-latest
+ timeout-minutes: 10
+ env:
+ DOCKER_TOKEN: ${{ secrets.DOCKER_TOKEN }}
+ steps:
+ - uses: actions/checkout@v3
+ - uses: actions/download-artifact@v3
+ with:
+ name: xqerl-image
+ - name: Load image
+ run: |
+ podman load --input xqerl.tar
+ podman images
+ printf %60s | tr ' ' '-' && echo
+ # localhost/xqerl
+ - name: GitHub Container Registry Login
+ uses: docker/login-action@v2
+ with:
+ registry: ghcr.io
+ username: ${{ github.actor }}
+ password: ${{ secrets.GITHUB_TOKEN }}
+ - name: Push to GitHub Container Registry
+ run: |
+ XQERL_VERSION=$(grep -oP 'v\d+\.\d+\.\d+' rebar.config)
+ buildah tag localhost/xqerl ghcr.io/${GITHUB_REPOSITORY}:${XQERL_VERSION}
+ buildah push ghcr.io/${GITHUB_REPOSITORY}:${XQERL_VERSION}
+ # - name: Login to Docker Container Registry
+ # if: ${{ env.DOCKER_TOKEN != '' }} && ${{ github.ref_type == 'tag' }}
+ # uses: docker/login-action@v2
+ # with:
+ # registry: docker.io
+ # username: ${{ github.actor }}
+ # password: ${{ env.DOCKER_TOKEN }}
+ # - name: Push to Docker Container Registry
+ # if: ${{ env.DOCKER_TOKEN != '' }} && ${{ github.ref_type == 'tag' }}
+ # run: |
+ # XQERL_VERSION=$(grep -oP 'v\d+\.\d+\.\d+' rebar.config)
+ # buildah tag localhost/xqerl docker.io/${GITHUB_REPOSITORY}:${XQERL_VERSION}
+ # buildah push docker.io/${GITHUB_REPOSITORY}:${XQERL_VERSION}
+ # buildah tag localhost/xqerl docker.io/${GITHUB_REPOSITORY}:latest
+ # buildah push docker.io/${GITHUB_REPOSITORY}:latest
diff --git a/.github/workflows/xqerl-slim-tar.yml b/.github/workflows/xqerl-slim-tar.yml
new file mode 100644
index 00000000..27fc4b20
--- /dev/null
+++ b/.github/workflows/xqerl-slim-tar.yml
@@ -0,0 +1,88 @@
+# Runs in official erlang:slim container
+# - builds production tar
+# if annotated tag then
+# - create release using gh cli
+name: debian ubuntu etc release
+on:
+ workflow_call:
+jobs:
+ xqerl_slim_build:
+ runs-on: ubuntu-latest
+ timeout-minutes: 10
+ container: erlang:slim
+ steps:
+ - uses: actions/checkout@v3
+ - name: Restore Cache
+ id: cache-deps
+ uses: actions/cache@v3
+ with:
+ path: _build
+ key: rebar-${{ hashFiles('./rebar.lock') }}
+ - name: Create Cache
+ if: steps.cache-deps.outputs.cache-hit != 'true'
+ run: |
+ rebar3 deps
+ rebar3 compile
+ - name: Build Production Tar
+ run: |
+ OTP_VERSION=$(cat /usr/local/lib/erlang/releases/*/OTP_VERSION)
+ OS_VERSION=$(cat /etc/os-release | grep -oP 'VERSION_ID=\K.+')
+ SLIM_PRETTY=$(cat /etc/os-release | grep -oP 'PRETTY_NAME=\K.+')
+ XQERL_VERSION=v$(grep -oP 'vsn.+\K\d+\.\d+\.\d+' src/xqerl.app.src)
+ echo " - xqerl release version: ${XQERL_VERSION}"
+ echo " - uses erlang OTP version: ${OTP_VERSION}"
+ echo " - built on: ${SLIM_PRETTY}"
+ rebar3 as prod tar
+ mkdir -p _release
+ mv _build/prod/rel/xqerl/xqerl-${XQERL_VERSION}.tar.gz _release/xqerl-slim.tar.gz
+ - name: Untar Then Run XQerl
+ run: |
+ mkdir /usr/local/xqerl
+ tar -zxf _release/xqerl-slim.tar.gz -C /usr/local/xqerl
+ cd /usr/local/bin
+ ln -s /usr/local/xqerl/bin/xqerl
+ cd ~/
+ xqerl daemon
+ sleep 5
+ echo -n ' - xqerl application started: '
+ xqerl eval 'application:ensure_all_started(xqerl).' | grep -oP 'ok'
+ xqerl eval "file:make_symlink(code:priv_dir(xqerl),\"./priv\")."
+ echo -n ' - network ping: '
+ xqerl ping | grep -oP 'pong'
+ - name: Upload built artifact
+ uses: actions/upload-artifact@v3
+ with:
+ name: xqerl-slim
+ path: _release/xqerl-slim.tar.gz
+ - id: run_info
+ run: |
+ echo 'gh run id ${{ github.run_id }}'
+ echo 'git commit sha ${{ github.sha }}'
+ echo 'git ref type ${{ github.ref_type }}'
+ echo 'git ref name ${{ github.ref_name }}'
+ echo 'gh workflow ${{ github.workflow }}'
+ echo "run_id=${{ github.run_id }}" >> $GITHUB_OUTPUT
+ release:
+ if: ${{ github.ref_type == 'tag' }}
+ needs: xqerl_slim_build
+ runs-on: ubuntu-latest
+ timeout-minutes: 10
+ steps:
+ - uses: actions/checkout@v3
+ - uses: actions/download-artifact@v3
+ - name: Release artifact
+ env:
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+ run: |
+ echo " - release version: ${{github.ref_name}}"
+ # - derive NOTE from the annotated tag message
+ NOTE="$(git tag -l --format='%(contents:subject)' ${{github.ref_name}} )"
+ echo " - release note: ${NOTE}"
+ # in build we detirmined that rebar.config version is the same as pushed annotated tag
+ # so we can just use ${{github.ref_name}} for the release name
+ # use the gh client to create release
+ gh release create ${{github.ref_name}} "./xqerl-slim/xqerl-slim.tar.gz#xqerl ${{github.ref_name}}" \
+ --notes "${NOTE}" \
+ --title "xqerl ubuntu release ${{github.ref_name}}" \
+ --target ${{github.sha}}
+
diff --git a/.github/workflows/xqerl.yml b/.github/workflows/xqerl.yml
index ac7426a9..013b76f4 100644
--- a/.github/workflows/xqerl.yml
+++ b/.github/workflows/xqerl.yml
@@ -1,4 +1,7 @@
-# https://docs.github.com/en/actions/learn-github-actions/expressions
+# this workflow runs
+# 1. when we merge a pull request into the main branch
+# 2. push an annotated tag on the main branch
+# The main checks are done on pushes to feature branches
name: build check release
on:
push:
@@ -7,7 +10,7 @@ on:
tags:
- 'v*.*.*'
jobs:
- build:
+ vsn_checks:
runs-on: ubuntu-latest
steps:
- name: checkout repo
@@ -43,234 +46,14 @@ jobs:
# A pushed tag may be lightwieght tag therefor no subject
[ ! -z "${NOTE}" ] || echo 'ERR: lightweight tag pushed. use annotated tag to create release'
[ ! -z "${NOTE}" ]
- #echo " - rebar_release: ${{ env.rebar_release}} "
- #echo " - xqerl app vsn: ${{ env.app_vsn }} "
- - name: Cache dependencies
- id: cache-deps
- uses: actions/cache@v2
- with:
- path: _build
- key: rebar-${{ hashFiles('./rebar.lock') }}
- - name: Cache dependencies
- if: steps.cache-deps.outputs.cache-hit != 'true'
- run: |
- rebar3 deps
- rebar3 compile
- - name: build production tar
- run: |
- rebar3 as prod tar
- mv _build/prod/rel/xqerl/xqerl-*.tar.gz ./xqerl.tar.gz
- - name: Upload built artifact
- uses: actions/upload-artifact@v3
- with:
- name: xqerl-prod-tar
- path: ./xqerl.tar.gz
- checks:
- if: ${{ github.ref_type == 'branch' }}
- needs: build
- runs-on: ubuntu-latest
- steps:
- - name: checkout repo
- uses: actions/checkout@v3
- - name: Download built artifact
- uses: actions/download-artifact@v3
- with:
- name: xqerl-prod-tar
- - name: Unpack release tar and install xqerl application
- run: |
- mkdir -p $HOME/.local/xqerl
- mkdir -p $HOME/.local/bin
- # echo "$HOME/.local/bin" >> $GITHUB_PATH
- tar -zxf xqerl.tar.gz -C $HOME/.local/xqerl
- ln -s $HOME/.local/xqerl/bin/xqerl $HOME/.local/bin
- which xqerl
- - name: Start the xqerl application
- run: |
- xqerl daemon
- sleep 2
- xqerl eval 'application:ensure_all_started(xqerl).'
- - name: Checks - OTP Beam inspection
- run: |
- printf %60s | tr ' ' '-' && echo
- echo -n '- ping: '
- xqerl ping | grep -oP 'pong'
- echo -n '- pid: '
- xqerl pid | grep -oP '\d+'
- printf %60s | tr ' ' '-' && echo
- echo -n ' - set xqerl working directory: '
- xqerl eval "file:set_cwd('$(pwd)')."
- xqerl eval 'file:get_cwd().'
- printf %60s | tr ' ' '=' && echo
- - name: Checks - xqerl eval on running instance
- run: |
- printf %60s | tr ' ' '-' && echo
- echo ' - run a xQuery expression'
- xqerl eval 'xqerl:run("xs:token(\"cats\"), xs:string(\"dogs\"), true() ").' | \
- grep -oP '^\[\{xq.+$'
- printf %60s | tr ' ' '-' && echo
- echo ' - compile an xQuery file'
- xqerl eval 'xqerl:compile("docs/src/sudoku2.xq").' | \
- grep -oP 'file(.+)\.xq'
- printf %60s | tr ' ' '-' && echo
- echo ' - compile, run then grep the title'
- xqerl eval 'S = xqerl:compile("docs/src/sudoku2.xq"),binary_to_list(xqerl_node:to_xml(S:main(#{}))).' | \
- grep -oP '(.+)'
- printf %60s | tr ' ' '-' && echo
- echo -n ' - load an XML file into the DB: '
- xqerl eval \
- 'xqldb_dml:insert_doc("http://xqerl.org/my_doc.xml","./test/QT3-test-suite/app/FunctxFn/functx_order.xml").' | \
- grep -oP 'ok'
- printf %60s | tr ' ' '-' && echo
- echo ' - view using the the xqerl:run/1 function with xQuery fn:doc#1 function'
- xqerl eval "binary_to_list(xqerl:run(\" 'http://xqerl.org/my_doc.xml' => doc() => serialize() \"))."
- printf %60s | tr ' ' '-' && echo
- echo -n ' - delete db doc '
- xqerl eval 'xqldb_dml:delete_doc("http://xqerl.org/my_doc.xml").' | \
- grep -oP 'ok'
- printf %60s | tr ' ' '-' && echo
- echo -n ' - import into DB docs from directory: '
- xqerl eval 'xqldb_dml:import_from_directory("http://xqerl.org/tests/", "./test/QT3-test-suite").' | \
- grep -oP 'ok'
- printf %60s | tr ' ' '=' && echo
- - name: Stop xqerl
- run: xqerl stop
- release:
+ build_check:
+ needs: vsn_checks
+ uses: ./.github/workflows/build-check.yml
+ tar_release:
if: ${{ github.ref_type == 'tag' }}
- needs: build
- runs-on: ubuntu-latest
- steps:
- - name: checkout repo
- uses: actions/checkout@v3
- - name: Download built artifact
- uses: actions/download-artifact@v3
- with:
- name: xqerl-prod-tar
- - name: Release artifact
- env:
- GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- run: |
- echo " - release version: ${{github.ref_name}}"
- # - derive NOTE from the annotated tag message
- NOTE="$(git tag -l --format='%(contents:subject)' ${{github.ref_name}} )"
- echo " - release note: ${NOTE}"
- # in build we detirmined that rebar.config version is the same as pushed annotated tag
- # so we can just use ${{github.ref_name}} for the release name
- # mv ./xqerl.tar.gz ./xqerl-${{github.ref_name}}.tar.gz
- # use the gh client to create release
- gh release create ${{github.ref_name}} "./xqerl.tar.gz#xqerl ${{github.ref_name}}" \
- --notes "${NOTE}" \
- --title "xqerl release ${{github.ref_name}}" \
- --target ${{github.sha}}
- package:
+ needs: build_check
+ uses: ./.github/workflows/xqerl-slim-tar.yml
+ container_release:
+ needs: vsn_checks
if: ${{ github.ref_type == 'tag' }}
- needs: build
- runs-on: ubuntu-latest
- steps:
- - uses: actions/checkout@v3
- - name: Pull Images
- run: |
- XQERL_VERSION=$(grep -oP 'v\d+\.\d+\.\d+' rebar.config)
- # pull in the latest versions of alpine and erlang alpine
- podman pull docker.io/alpine:latest
- ALPINE_VERSION=$(podman run --rm docker.io/alpine:latest /bin/ash -c 'cat /etc/os-release' | grep -oP 'VERSION_ID=\K.+')
- podman pull docker.io/erlang:alpine
- OTP_VERSION=$(podman run --rm docker.io/erlang:alpine sh -c 'cat /usr/local/lib/erlang/releases/*/OTP_VERSION')
- echo " - release version: ${XQERL_VERSION}"
- echo " - uses alpine version: ${ALPINE_VERSION}"
- echo " - uses erlang OTP version: ${OTP_VERSION}"
- - name: Buildah
- run: |
- XQERL_VERSION=$(grep -oP 'v\d+\.\d+\.\d+' rebar.config)
- BASE_CONTAINER=$(buildah from docker.io/erlang:alpine)
- buildah copy ${BASE_CONTAINER} ./ /home/
- buildah run ${BASE_CONTAINER} sh -c 'apk add --update git tar \
- && cd /home \
- && rebar3 as prod tar \
- && mkdir /usr/local/xqerl \
- && tar -zxf _build/prod/rel/xqerl/*.tar.gz -C /usr/local/xqerl'
- CONTAINER=$(buildah from docker.io/alpine:latest)
- buildah run ${CONTAINER} sh -c 'apk add --no-cache openssl ncurses-libs tzdata libstdc++ \
- && mkdir /usr/local/xqerl \
- && cd /usr/local/bin \
- && ln -s /usr/local/xqerl/bin/xqerl'
- buildah copy --from ${BASE_CONTAINER} $CONTAINER /usr/local/xqerl /usr/local/xqerl
- printf %60s | tr ' ' '-' && echo
- echo " - check"
- buildah run ${CONTAINER} sh -c 'which xqerl' # should error if fails to find
- echo " - set working dir and entry point"
- buildah config --cmd '' ${CONTAINER}
- buildah config --workingdir /usr/local/xqerl ${CONTAINER}
- buildah config --entrypoint '[ "xqerl", "foreground"]' ${CONTAINER}
- echo " - set environment vars"
- buildah config --env LANG=C.UTF-8 ${CONTAINER}
- buildah config --env HOME=/home ${CONTAINER}
- buildah config --env XQERL_HOME=/usr/local/xqerl ${CONTAINER}
- printf %60s | tr ' ' '-' && echo
- buildah run ${CONTAINER} sh -c 'printenv' || true
- printf %60s | tr ' ' '-' && echo
- echo " - set stop signal"
- buildah config --stop-signal SIGTERM ${CONTAINER}
- echo " - set labels"
- buildah config --label org.opencontainers.image.base.name=alpine ${CONTAINER}
- buildah config --label org.opencontainers.image.title='xqerl' ${CONTAINER}
- buildah config --label org.opencontainers.image.description='Erlang XQuery 3.1 Processor and XML Database' ${CONTAINER}
- buildah config --label org.opencontainers.image.source=https://github.com/${GITHUB_REPOSITORY} ${CONTAINER} # where the image is built
- buildah config --label org.opencontainers.image.documentation=https://github.com//${GITHUB_REPOSITORY} ${CONTAINER} # image documentation
- buildah config --label org.opencontainers.image.version=${XQERL_VERSION} ${CONTAINER} # version
- buildah run ${CONTAINER} sh -c \
- 'xqerl daemon && sleep 2 && xqerl eval "file:make_symlink(code:priv_dir(xqerl),\"./priv\")." && xqerl stop'
- buildah commit --squash --rm ${CONTAINER} localhost/xqerl
- printf %60s | tr ' ' '-' && echo
- - name: Container Checks
- run: |
- echo " - list docker images"
- podman images
- printf %60s | tr ' ' '-' && echo
- echo " - run container with sh as entrypoint and list working directories"
- podman run --rm --entrypoint '["/bin/sh", "-c"]' localhost/xqerl 'ls -al .'
- echo " - run container with published ports"
- podman run --name xq --publish 8081:8081 --detach localhost/xqerl
- sleep 4
- echo -n ' - check running: '
- podman container inspect -f '{{.State.Running}}' xq
- echo -n ' - check application all started: '
- podman exec xq xqerl eval "application:ensure_all_started(xqerl)." | grep -oP '^.\Kok'
- echo " - check log - only show supervisor"
- printf %60s | tr ' ' '-' && echo
- podman logs -n -t --since 0 -l | grep -oP '^.+\Ksupervisor:.+$'
- printf %60s | tr ' ' '-' && echo
- echo -n ' - check status and running size: '
- podman ps --size --format "{{.Names}} {{.Status}} {{.Size}}"
- echo ' - display the running processes of the container: '
- podman top xq user pid %C
- podman stop xq || true
- - name: Login to GitHub Container Registry
- uses: docker/login-action@v2
- with:
- registry: ghcr.io
- username: ${{ github.actor }}
- password: ${{ secrets.GITHUB_TOKEN }}
- - name: Push to GitHub Container Registry
- run: |
- XQERL_VERSION=$(grep -oP 'v\d+\.\d+\.\d+' rebar.config)
- buildah tag localhost/xqerl ghcr.io/${GITHUB_REPOSITORY}:${XQERL_VERSION}
- buildah push ghcr.io/${GITHUB_REPOSITORY}:${XQERL_VERSION}
- - name: Login to Docker Container Registry
- env:
- DOCKER_TOKEN: ${{ secrets.DOCKER_TOKEN }}
- if: "${{ env.DOCKER_TOKEN != '' }}"
- uses: docker/login-action@v1
- with:
- registry: docker.io
- username: ${{ github.actor }}
- password: ${{ secrets.DOCKER_TOKEN }}
- - name: Push to Docker Container Registry
- env:
- DOCKER_TOKEN: ${{ secrets.DOCKER_TOKEN }}
- if: "${{ env.DOCKER_TOKEN != '' }}"
- run: |
- XQERL_VERSION=$(grep -oP 'v\d+\.\d+\.\d+' rebar.config)
- buildah tag localhost/xqerl docker.io/${GITHUB_REPOSITORY}:${XQERL_VERSION}
- buildah push docker.io/${GITHUB_REPOSITORY}:${XQERL_VERSION}
- buildah tag localhost/xqerl docker.io/${GITHUB_REPOSITORY}:latest
- buildah push docker.io/${GITHUB_REPOSITORY}:latest
+ uses: ./.github/workflows/xqerl-alpine-image.yml
diff --git a/priv/bin/list-db-uri b/priv/bin/list-db-uri
index 32cae092..13246f69 100644
--- a/priv/bin/list-db-uri
+++ b/priv/bin/list-db-uri
@@ -32,7 +32,7 @@ main([]) ->
try rpc:call( 'xqerl@127.0.0.1',
xqerl,
run,
- ["for-each(uri-collection(),function($item){uri-collection($item)})"],
+ ["try {(uri-collection() ! uri-collection(.)) => distinct-values()} catch * {()}"],
Timeout) of
E when is_record(E, xqError) -> formatError(E);
A when is_record(A, xqAtomicValue) -> print([A]);
diff --git a/rebar.config b/rebar.config
index 203a29f0..bf707e5b 100644
--- a/rebar.config
+++ b/rebar.config
@@ -1,38 +1,36 @@
{minimum_otp_vsn, "24.1"}.
{deps, [
- {xs_regex, "0.1.0"},
- {erluca, "0.1.1"},
- {merge_index, "2.1.0", {pkg, xqerl_merge_index}},
+ {basexerl, "0.1.2"},
+ {cowboy, "2.10.0"},
{emojipoo, "0.1.0"},
+ {erluca, "0.1.2"},
+ {hackney, "1.18.1"},
{htmerl, "0.1.0"},
- {hackney, "1.18.0"},
- {cowboy, "2.9.0"},
- {sext, "1.8.0"},
{locks, "0.2.0"},
- {uuid, "2.0.4", {pkg, uuid_erl}},
- {basexerl, "0.1.2"},
- {yaccety_sax, "0.2.3"}
-]}.
-
-{erl_opts, [
- {i, "include"},
- debug_info
+ {merge_index, "2.1.0", {pkg, xqerl_merge_index}},
+ {sext, "1.8.0"},
+ {uuid, "2.0.5", {pkg, uuid_erl}},
+ {xs_regex, "0.1.0"},
+ {yaccety_sax, "0.3.0"}
]}.
-
+{erl_opts, [{i, "include"}, debug_info]}.
{edoc_opts, [{preprocess, true}]}.
+
{ex_doc, [
{homepage_url, <<"http://xqerl.org">>},
{source_url, <<"https://github.com/zadean/xqerl">>},
{logo, <<"./docs/img/Squirrel.png">>},
- {extras, [<<"README.md">>, <<"LICENSE">>, <<"./docs/src/GettingStarted.md">>]},
+ {extras, [
+ <<"README.md">>,
+ <<"LICENSE">>,
+ <<"./docs/src/GettingStarted.md">>
+ ]},
{main, <<"readme">>}
]}.
-
{hex, [{doc, ex_doc}]}.
-{project_plugins, [erlfmt]}.
-
+{project_plugins, [erlfmt, rebar3_depup]}.
{erlfmt, [write]}.
{shell, [{config, "config/xqerl.config"}]}.
@@ -49,7 +47,6 @@
{dev_mode, false},
{include_src, false},
{include_erts, true}
- % {debug_info, strip} TODO!
]}
]}
]}.
@@ -61,9 +58,5 @@
{dev_mode, true},
{include_erts, false},
{extended_start_script, true},
- {overlay, [
- {mkdir, "log"},
- {mkdir, "code"},
- {mkdir, "data"}
- ]}
+ {overlay, [{mkdir, "log"}, {mkdir, "code"}, {mkdir, "data"}]}
]}.