From 1ac25c34111cbcc807c2a70648d5cffd52e41567 Mon Sep 17 00:00:00 2001 From: Zachary Dean Date: Sat, 5 Nov 2022 12:38:50 +0100 Subject: [PATCH 01/13] Fix case when opening DBs are not seen --- src/xqldb_db_server.erl | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/xqldb_db_server.erl b/src/xqldb_db_server.erl index 760dd736..8d0206c2 100644 --- a/src/xqldb_db_server.erl +++ b/src/xqldb_db_server.erl @@ -140,6 +140,7 @@ do_get_open(Path, Ets) -> MPattern = Path ++ '$1', MatchSpec = [ {{{MPattern, '_', '_'}, '_', open}, [], ['$1']}, + {{{MPattern, '_', '_'}, '_', opening}, [], ['$1']}, {{{MPattern, '_', '_'}, '_', closed}, [], ['$1']} ], Res = ets:select(Ets, MatchSpec), @@ -283,13 +284,14 @@ handle_call({info, Path, _Uri}, _From, #{tab := Ets} = State) -> {reply, {error, not_exists}, State}; [{{_, _, _}, _, missing}] -> {reply, {error, not_exists}, State}; - [{{_, _, Id}, Pid, Status}] when is_pid(Pid) -> + [{{_, Uri, Id}, Pid, Status}] when is_pid(Pid) -> % check if it is still alive case erlang:is_process_alive(Pid) of true -> {reply, {Status, Id, Pid}, State}; false -> - {reply, {error, not_exists}, State} + ets:insert(Ets, {{Path, Uri, Id}, undefined, closed}), + {reply, {closed, Id, undefined}, State} end; [{{_, _, Id}, undefined, opening}] -> {reply, {opening, Id, undefined}, State}; From f28b70134b78a371a6a902111447087883f60961 Mon Sep 17 00:00:00 2001 From: grantmacken Date: Sat, 17 Dec 2022 10:56:03 +1300 Subject: [PATCH 02/13] Bumped xqerl app to version v0.1.19 --- rebar.config | 2 +- src/xqerl.app.src | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/rebar.config b/rebar.config index 203a29f0..f2bce552 100644 --- a/rebar.config +++ b/rebar.config @@ -55,7 +55,7 @@ ]}. {relx, [ - {release, {xqerl, "v0.2.0"}, [xqerl]}, + {release, {xqerl, "v0.1.19"}, [xqerl]}, {sys_config, "config/xqerl.config"}, {vm_args_src, "config/vm.args.src"}, {dev_mode, true}, diff --git a/src/xqerl.app.src b/src/xqerl.app.src index cfd6de0d..c879dd37 100644 --- a/src/xqerl.app.src +++ b/src/xqerl.app.src @@ -1,6 +1,6 @@ {application, xqerl, [ {description, "XQuery 3.1 Processor"}, - {vsn, "0.2.0"}, + {vsn, "0.1.19"}, {applications, [ kernel, stdlib, From a0555ab966972801f73fe37d9df8b9091946bed8 Mon Sep 17 00:00:00 2001 From: grantmacken Date: Sun, 29 Jan 2023 07:39:28 +1300 Subject: [PATCH 03/13] ci refactor due to missing erlang in ubuntu latest runner --- .github/workflows/build-check.yml | 870 ++++++++++++++++++++++ .github/workflows/container.yml | 115 --- .github/workflows/feat.yml | 874 +--------------------- .github/workflows/xqerl-alpine-image.yml | 908 +++++++++++++++++++++++ .github/workflows/xqerl-slim-tar.yml | 88 +++ .github/workflows/xqerl.yml | 245 +----- 6 files changed, 1898 insertions(+), 1202 deletions(-) create mode 100644 .github/workflows/build-check.yml delete mode 100644 .github/workflows/container.yml create mode 100644 .github/workflows/xqerl-alpine-image.yml create mode 100644 .github/workflows/xqerl-slim-tar.yml diff --git a/.github/workflows/build-check.yml b/.github/workflows/build-check.yml new file mode 100644 index 00000000..74631514 --- /dev/null +++ b/.github/workflows/build-check.yml @@ -0,0 +1,870 @@ +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 + tar -zxf _release/xqerl.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-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\")." + echo -n ' - set xqerl working directory: ' + xqerl eval "file:set_cwd('$(pwd)')." + xqerl eval 'file:get_cwd().' + 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_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 + tar -zxf xqerl.tar.gz -C /usr/local/xqerl + cd /usr/local/bin + ln -s /usr/local/xqerl/bin/xqerl + cd ~/ + xqerl daemon + sleep 5 + xqerl eval "file:make_symlink(code:priv_dir(xqerl),\"./priv\")." + echo -n ' - set xqerl working directory: ' + xqerl eval "file:set_cwd('$(pwd)')." + - 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 + tar -zxf xqerl.tar.gz -C /usr/local/xqerl + cd /usr/local/bin + ln -s /usr/local/xqerl/bin/xqerl + cd ~/ + xqerl daemon + sleep 5 + xqerl eval "file:make_symlink(code:priv_dir(xqerl),\"./priv\")." + echo -n ' - set xqerl working directory: ' + xqerl eval "file:set_cwd('$(pwd)')." + - 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 From 567bc72f24be2797bb3341ebee9a2ea8b8f2c15d Mon Sep 17 00:00:00 2001 From: grantmacken Date: Sun, 29 Jan 2023 07:57:24 +1300 Subject: [PATCH 04/13] refactor: replace foreach with bang --- priv/bin/list-db-uri | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/priv/bin/list-db-uri b/priv/bin/list-db-uri index 32cae092..15d9062e 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)})"], + ["uri-collection() ! uri-collection(.)"], Timeout) of E when is_record(E, xqError) -> formatError(E); A when is_record(A, xqAtomicValue) -> print([A]); From 73d6280425c6e310da45d4c66e5f8e44a3e6143a Mon Sep 17 00:00:00 2001 From: grantmacken Date: Sun, 29 Jan 2023 08:01:59 +1300 Subject: [PATCH 05/13] chore: rest vsn --- rebar.config | 2 +- src/xqerl.app.src | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/rebar.config b/rebar.config index f2bce552..203a29f0 100644 --- a/rebar.config +++ b/rebar.config @@ -55,7 +55,7 @@ ]}. {relx, [ - {release, {xqerl, "v0.1.19"}, [xqerl]}, + {release, {xqerl, "v0.2.0"}, [xqerl]}, {sys_config, "config/xqerl.config"}, {vm_args_src, "config/vm.args.src"}, {dev_mode, true}, diff --git a/src/xqerl.app.src b/src/xqerl.app.src index c879dd37..cfd6de0d 100644 --- a/src/xqerl.app.src +++ b/src/xqerl.app.src @@ -1,6 +1,6 @@ {application, xqerl, [ {description, "XQuery 3.1 Processor"}, - {vsn, "0.1.19"}, + {vsn, "0.2.0"}, {applications, [ kernel, stdlib, From 2de1f0b5d969dea9f9e0f9cfcb5494e024ca04dd Mon Sep 17 00:00:00 2001 From: grantmacken Date: Sun, 29 Jan 2023 08:18:54 +1300 Subject: [PATCH 06/13] chore: update vsn for yaccety_sax etc --- rebar.config | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/rebar.config b/rebar.config index 203a29f0..a2aa19e6 100644 --- a/rebar.config +++ b/rebar.config @@ -6,13 +6,13 @@ {merge_index, "2.1.0", {pkg, xqerl_merge_index}}, {emojipoo, "0.1.0"}, {htmerl, "0.1.0"}, - {hackney, "1.18.0"}, + {hackney, "1.18.1"}, {cowboy, "2.9.0"}, {sext, "1.8.0"}, {locks, "0.2.0"}, - {uuid, "2.0.4", {pkg, uuid_erl}}, + {uuid, "2.0.5", {pkg, uuid_erl}}, {basexerl, "0.1.2"}, - {yaccety_sax, "0.2.3"} + {yaccety_sax, "0.3.0"} ]}. {erl_opts, [ From 38f902d45d09e8f7ce50980aa4da9898409fffb8 Mon Sep 17 00:00:00 2001 From: grantmacken Date: Sun, 29 Jan 2023 08:46:02 +1300 Subject: [PATCH 07/13] update deps --- rebar.config | 107 ++++++++++++++++++++++----------------------------- 1 file changed, 46 insertions(+), 61 deletions(-) diff --git a/rebar.config b/rebar.config index a2aa19e6..a8d55e25 100644 --- a/rebar.config +++ b/rebar.config @@ -1,69 +1,54 @@ {minimum_otp_vsn, "24.1"}. -{deps, [ - {xs_regex, "0.1.0"}, - {erluca, "0.1.1"}, - {merge_index, "2.1.0", {pkg, xqerl_merge_index}}, - {emojipoo, "0.1.0"}, - {htmerl, "0.1.0"}, - {hackney, "1.18.1"}, - {cowboy, "2.9.0"}, - {sext, "1.8.0"}, - {locks, "0.2.0"}, - {uuid, "2.0.5", {pkg, uuid_erl}}, - {basexerl, "0.1.2"}, - {yaccety_sax, "0.3.0"} -]}. - -{erl_opts, [ - {i, "include"}, - debug_info -]}. - + {deps, + [{xs_regex, "0.1.0"}, + {erluca, "0.1.1"}, + {merge_index, "2.1.0", {pkg, xqerl_merge_index}}, + {emojipoo, "0.1.0"}, + {htmerl, "0.1.0"}, + {hackney, "1.18.1"}, + {cowboy, "2.9.0"}, + {sext, "1.8.0"}, + {locks, "0.2.0"}, + {uuid, "2.0.5", {pkg, uuid_erl}}, + {basexerl, "0.1.2"}, + {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">>]}, - {main, <<"readme">>} -]}. + {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">>]}, + {main, <<"readme">>}]}. {hex, [{doc, ex_doc}]}. -{project_plugins, [erlfmt]}. - + {project_plugins, [erlfmt, rebar3_depup]}. {erlfmt, [write]}. -{shell, [{config, "config/xqerl.config"}]}. - -{profiles, [ - {test, [ - {ct_opts, [ - {sys_config, ["config/xqerl.test.config"]}, - {logopts, [no_src]} - ]} - ]}, - {prod, [ - {relx, [ - {dev_mode, false}, - {include_src, false}, - {include_erts, true} - % {debug_info, strip} TODO! - ]} - ]} -]}. - -{relx, [ - {release, {xqerl, "v0.2.0"}, [xqerl]}, - {sys_config, "config/xqerl.config"}, - {vm_args_src, "config/vm.args.src"}, - {dev_mode, true}, - {include_erts, false}, - {extended_start_script, true}, - {overlay, [ - {mkdir, "log"}, - {mkdir, "code"}, - {mkdir, "data"} - ]} -]}. + {shell, [{config, "config/xqerl.config"}]}. + + {profiles, + [{test, + [{ct_opts, + [{sys_config, ["config/xqerl.test.config"]}, + {logopts, [no_src]}]}]}, + {prod, + [{relx, + [{dev_mode, false}, + {include_src, false}, + {include_erts, true}]}]}]}. + + {relx, + [{release, {xqerl, "v0.2.0"}, [xqerl]}, + {sys_config, "config/xqerl.config"}, + {vm_args_src, "config/vm.args.src"}, + {dev_mode, true}, + {include_erts, false}, + {extended_start_script, true}, + {overlay, + [{mkdir, "log"}, {mkdir, "code"}, {mkdir, "data"}]}]}. \ No newline at end of file From fd74658c0b0d8e64607eef8f7b90f6eda3b8a20f Mon Sep 17 00:00:00 2001 From: grantmacken Date: Sun, 29 Jan 2023 10:55:32 +1300 Subject: [PATCH 08/13] fix: add try to catch err if no databases --- priv/bin/list-db-uri | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/priv/bin/list-db-uri b/priv/bin/list-db-uri index 15d9062e..ed9428cb 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, - ["uri-collection() ! uri-collection(.)"], + ["try {uri-collection() ! uri-collection(.)} catch * {()}"], Timeout) of E when is_record(E, xqError) -> formatError(E); A when is_record(A, xqAtomicValue) -> print([A]); From 45f2254218d5b64675221a6da7d7bfdd28a3dffb Mon Sep 17 00:00:00 2001 From: grantmacken Date: Fri, 24 Feb 2023 10:35:10 +1300 Subject: [PATCH 09/13] fix: distinct values for db entries --- priv/bin/list-db-uri | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/priv/bin/list-db-uri b/priv/bin/list-db-uri index ed9428cb..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, - ["try {uri-collection() ! uri-collection(.)} catch * {()}"], + ["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]); From aff00e50f44c8abd7a9deef573b805a37a926a11 Mon Sep 17 00:00:00 2001 From: grantmacken Date: Thu, 15 Jun 2023 08:10:00 +1200 Subject: [PATCH 10/13] format rebar3 file --- .github/workflows/build-check.yml | 457 +++++++++++++----------------- rebar.config | 92 +++--- 2 files changed, 254 insertions(+), 295 deletions(-) diff --git a/.github/workflows/build-check.yml b/.github/workflows/build-check.yml index 74631514..dbff846a 100644 --- a/.github/workflows/build-check.yml +++ b/.github/workflows/build-check.yml @@ -1,9 +1,9 @@ name: build and checks on running xqerl instance on: workflow_call: -jobs: - build_with_erlang_alpine: - runs-on: ubuntu-latest + jobs: + build_with_erlang_alpine: + runs-on: ubuntu-latest timeout-minutes: 10 container: erlang:alpine steps: @@ -30,40 +30,31 @@ jobs: 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}" + 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 - tar -zxf _release/xqerl.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' + 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 + 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 @@ -79,43 +70,26 @@ jobs: which xqerl xqerl daemon sleep 2 - - name: Checks - xqerl eval on running instance - run: | - xqerl eval "file:make_symlink(code:priv_dir(xqerl),\"./priv\")." - echo -n ' - set xqerl working directory: ' - xqerl eval "file:set_cwd('$(pwd)')." - xqerl eval 'file:get_cwd().' - 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 - + 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 @@ -142,32 +116,24 @@ jobs: 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 + 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 - tar -zxf xqerl.tar.gz -C /usr/local/xqerl - cd /usr/local/bin - ln -s /usr/local/xqerl/bin/xqerl - cd ~/ - xqerl daemon - sleep 5 - xqerl eval "file:make_symlink(code:priv_dir(xqerl),\"./priv\")." - echo -n ' - set xqerl working directory: ' - xqerl eval "file:set_cwd('$(pwd)')." + 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 @@ -178,24 +144,24 @@ jobs: 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 ' ' '=' + --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 @@ -206,24 +172,24 @@ jobs: 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 ' ' '=' + --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 @@ -234,25 +200,24 @@ jobs: 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 ' ' '=' - + --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 @@ -268,26 +233,25 @@ jobs: 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 ' ' '=' - + --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 @@ -298,38 +262,38 @@ jobs: 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 + --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 + --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 ' ----------------' @@ -348,16 +312,16 @@ jobs: 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 + --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 ' ----------------' @@ -406,7 +370,7 @@ jobs: 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' \ + --head -H 'Accept: text/plain' \ http://localhost:8081/db/${COLLECTION} > ${CHECK_PATH}/write-out.txt printf %60s | tr ' ' '=' && echo echo ' - show headers' @@ -429,7 +393,7 @@ jobs: 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' \ + --head -H 'Accept: application/xml' \ http://localhost:8081/db/${COLLECTION} > ${CHECK_PATH}/write-out.txt printf %60s | tr ' ' '=' && echo echo ' - show headers' @@ -452,7 +416,7 @@ jobs: 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' \ + --head -H 'Accept: application/xml' \ http://localhost:8081/db/${COLLECTION}/${RESOURCE} > ${CHECK_PATH}/write-out.txt printf %60s | tr ' ' '=' && echo echo ' - show headers' @@ -468,15 +432,15 @@ jobs: 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 + if grep -oP 'content-length: 0' ${CHECK_PATH}/headers.txt >/dev/null then - echo ' - header content length should be greater than zero: false' + echo ' - header content length should be greater than zero: false' false else - echo ' - header content length should be greater than zero: true' + echo ' - header content length should be greater than zero: true' fi printf %60s | tr ' ' '=' && echo - # NOTE: resource retrieval via Accept Header + # NOTE: resource retrieval via Accept Header - name: GET - accept XML - retrieve XDM document-node resource run: | CHECK=GET_ACCEPT_XML @@ -485,7 +449,7 @@ jobs: CHECK_PATH=checks/${CHECK}/${COLLECTION} mkdir -p $CHECK_PATH curl --silent --show-error --connect-timeout 1 --max-time 2 \ - --header 'Accept: application/xml' \ + --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} \ @@ -514,7 +478,7 @@ jobs: CHECK_PATH=checks/${CHECK}/${COLLECTION} mkdir -p $CHECK_PATH curl --silent --show-error --connect-timeout 1 --max-time 2 \ - --header 'Accept: application/json' \ + --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} \ @@ -543,7 +507,7 @@ jobs: CHECK_PATH=checks/${CHECK}/${COLLECTION} mkdir -p $CHECK_PATH curl --silent --show-error --connect-timeout 1 --max-time 2 \ - --header 'Accept: application/json' \ + --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} \ @@ -564,7 +528,6 @@ jobs: 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 @@ -573,7 +536,7 @@ jobs: CHECK_PATH=checks/${CHECK}/${COLLECTION} mkdir -p $CHECK_PATH curl --silent --show-error --connect-timeout 1 --max-time 2 \ - --header 'Accept: application/json' \ + --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} \ @@ -594,7 +557,6 @@ jobs: 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 @@ -603,7 +565,7 @@ jobs: CHECK_PATH=checks/${CHECK}/${COLLECTION} mkdir -p $CHECK_PATH curl --silent --show-error --connect-timeout 1 --max-time 2 \ - --header 'Accept: application/json' \ + --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} \ @@ -624,7 +586,6 @@ jobs: 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 @@ -633,7 +594,7 @@ jobs: CHECK_PATH=checks/${CHECK}/${COLLECTION} mkdir -p $CHECK_PATH curl --silent --show-error --connect-timeout 1 --max-time 2 \ - --header 'Accept: text/html' \ + --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} \ @@ -654,7 +615,6 @@ jobs: 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 @@ -663,7 +623,7 @@ jobs: CHECK_PATH=checks/${CHECK}/${COLLECTION} mkdir -p $CHECK_PATH curl --silent --show-error --connect-timeout 1 --max-time 2 \ - --header 'Accept: text/csv' \ + --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} \ @@ -684,7 +644,6 @@ jobs: 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 @@ -721,7 +680,7 @@ jobs: -X PUT \ --dump-header ${CHECK_PATH}/headers.txt \ --write-out 'response code [ %{http_code} ]\ncontent type [ %{content_type} ]\n' \ - --header 'Content-Type: application/xml' \ + --header 'Content-Type: application/xml' \ --data 'data' \ http://localhost:8081/db/${COLLECTION}/${RESOURCE} > ${CHECK_PATH}/write-out.txt printf %60s | tr ' ' '=' && echo @@ -806,40 +765,32 @@ jobs: 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 + 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 - tar -zxf xqerl.tar.gz -C /usr/local/xqerl - cd /usr/local/bin - ln -s /usr/local/xqerl/bin/xqerl - cd ~/ - xqerl daemon - sleep 5 - xqerl eval "file:make_symlink(code:priv_dir(xqerl),\"./priv\")." - echo -n ' - set xqerl working directory: ' - xqerl eval "file:set_cwd('$(pwd)')." + 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: ' + echo ' - compile library module: ' xqerl eval 'xqerl:compile("test/restxq/tests.xqm").' &>/dev/null - echo ' - db import some XML docs: ' + 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 @@ -852,19 +803,19 @@ jobs: 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: 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/rebar.config b/rebar.config index a8d55e25..6920c6b7 100644 --- a/rebar.config +++ b/rebar.config @@ -1,54 +1,62 @@ {minimum_otp_vsn, "24.1"}. - {deps, - [{xs_regex, "0.1.0"}, - {erluca, "0.1.1"}, - {merge_index, "2.1.0", {pkg, xqerl_merge_index}}, - {emojipoo, "0.1.0"}, - {htmerl, "0.1.0"}, - {hackney, "1.18.1"}, - {cowboy, "2.9.0"}, - {sext, "1.8.0"}, - {locks, "0.2.0"}, - {uuid, "2.0.5", {pkg, uuid_erl}}, - {basexerl, "0.1.2"}, - {yaccety_sax, "0.3.0"}]}. +{deps, [ + {xs_regex, "0.1.0"}, + {erluca, "0.1.1"}, + {merge_index, "2.1.0", {pkg, xqerl_merge_index}}, + {emojipoo, "0.1.0"}, + {htmerl, "0.1.0"}, + {hackney, "1.18.1"}, + {cowboy, "2.9.0"}, + {sext, "1.8.0"}, + {locks, "0.2.0"}, + {uuid, "2.0.5", {pkg, uuid_erl}}, + {basexerl, "0.1.2"}, + {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">>, +{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">>]}, - {main, <<"readme">>}]}. + <<"./docs/src/GettingStarted.md">> + ]}, + {main, <<"readme">>} +]}. {hex, [{doc, ex_doc}]}. - {project_plugins, [erlfmt, rebar3_depup]}. +{project_plugins, [erlfmt, rebar3_depup]}. {erlfmt, [write]}. - {shell, [{config, "config/xqerl.config"}]}. +{shell, [{config, "config/xqerl.config"}]}. - {profiles, - [{test, - [{ct_opts, - [{sys_config, ["config/xqerl.test.config"]}, - {logopts, [no_src]}]}]}, - {prod, - [{relx, - [{dev_mode, false}, - {include_src, false}, - {include_erts, true}]}]}]}. +{profiles, [ + {test, [ + {ct_opts, [ + {sys_config, ["config/xqerl.test.config"]}, + {logopts, [no_src]} + ]} + ]}, + {prod, [ + {relx, [ + {dev_mode, false}, + {include_src, false}, + {include_erts, true} + ]} + ]} +]}. - {relx, - [{release, {xqerl, "v0.2.0"}, [xqerl]}, - {sys_config, "config/xqerl.config"}, - {vm_args_src, "config/vm.args.src"}, - {dev_mode, true}, - {include_erts, false}, - {extended_start_script, true}, - {overlay, - [{mkdir, "log"}, {mkdir, "code"}, {mkdir, "data"}]}]}. \ No newline at end of file +{relx, [ + {release, {xqerl, "v0.2.0"}, [xqerl]}, + {sys_config, "config/xqerl.config"}, + {vm_args_src, "config/vm.args.src"}, + {dev_mode, true}, + {include_erts, false}, + {extended_start_script, true}, + {overlay, [{mkdir, "log"}, {mkdir, "code"}, {mkdir, "data"}]} +]}. From 67d53966ecd437b0d0ea0c8739adddd58326ec84 Mon Sep 17 00:00:00 2001 From: grantmacken Date: Thu, 15 Jun 2023 08:41:08 +1200 Subject: [PATCH 11/13] update cowboy ver --- rebar.config | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rebar.config b/rebar.config index 6920c6b7..8979836d 100644 --- a/rebar.config +++ b/rebar.config @@ -7,7 +7,7 @@ {emojipoo, "0.1.0"}, {htmerl, "0.1.0"}, {hackney, "1.18.1"}, - {cowboy, "2.9.0"}, + {cowboy, "2.10.0"}, {sext, "1.8.0"}, {locks, "0.2.0"}, {uuid, "2.0.5", {pkg, uuid_erl}}, From 25736b120c0347875813d9441df42b8a06550bd5 Mon Sep 17 00:00:00 2001 From: grantmacken Date: Thu, 15 Jun 2023 09:13:52 +1200 Subject: [PATCH 12/13] update erluca ver --- rebar.config | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rebar.config b/rebar.config index 8979836d..d4ac5a45 100644 --- a/rebar.config +++ b/rebar.config @@ -2,7 +2,7 @@ {deps, [ {xs_regex, "0.1.0"}, - {erluca, "0.1.1"}, + {erluca, "0.1.2"}, {merge_index, "2.1.0", {pkg, xqerl_merge_index}}, {emojipoo, "0.1.0"}, {htmerl, "0.1.0"}, From 6c1ca370cc91a48f44441bfb65859d41274bf252 Mon Sep 17 00:00:00 2001 From: grantmacken Date: Fri, 16 Jun 2023 06:42:16 +1200 Subject: [PATCH 13/13] sort deps --- rebar.config | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/rebar.config b/rebar.config index d4ac5a45..bf707e5b 100644 --- a/rebar.config +++ b/rebar.config @@ -1,17 +1,17 @@ {minimum_otp_vsn, "24.1"}. {deps, [ - {xs_regex, "0.1.0"}, - {erluca, "0.1.2"}, - {merge_index, "2.1.0", {pkg, xqerl_merge_index}}, + {basexerl, "0.1.2"}, + {cowboy, "2.10.0"}, {emojipoo, "0.1.0"}, - {htmerl, "0.1.0"}, + {erluca, "0.1.2"}, {hackney, "1.18.1"}, - {cowboy, "2.10.0"}, - {sext, "1.8.0"}, + {htmerl, "0.1.0"}, {locks, "0.2.0"}, + {merge_index, "2.1.0", {pkg, xqerl_merge_index}}, + {sext, "1.8.0"}, {uuid, "2.0.5", {pkg, uuid_erl}}, - {basexerl, "0.1.2"}, + {xs_regex, "0.1.0"}, {yaccety_sax, "0.3.0"} ]}. {erl_opts, [{i, "include"}, debug_info]}.