diff --git a/.env.dataverse b/.env.dataverse new file mode 100644 index 0000000..28c5050 --- /dev/null +++ b/.env.dataverse @@ -0,0 +1,4 @@ +POSTGRES_VERSION=13 +DATAVERSE_DB_USER=dataverse +SOLR_VERSION=8.11.1 +DATAVERSE_BOOTSTRAP_TIMEOUT=5m diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..dfe0770 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,2 @@ +# Auto detect text files and perform LF normalization +* text=auto diff --git a/.github/workflows/test-action.yml b/.github/workflows/test-action.yml new file mode 100644 index 0000000..9253427 --- /dev/null +++ b/.github/workflows/test-action.yml @@ -0,0 +1,19 @@ +on: [push] + +jobs: + custom_test: + runs-on: ubuntu-latest + name: Test the action + env: + PORT: 8080 + steps: + - name: "Checkout" + uses: "actions/checkout@v4" + - name: Run Dataverse Action + uses: ./ + with: + create-dv: true + - name: Check Dataverse Setup + run: | + echo $(curl http://localhost:8080/api/info/version) && \ + echo $(curl http://localhost:8080/api/metadatablocks) \ No newline at end of file diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..161d23f --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2023 Jan Range + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/README.md b/README.md new file mode 100644 index 0000000..9e31610 --- /dev/null +++ b/README.md @@ -0,0 +1,23 @@ +# Dataverse Configbaker Action + +This GitHub Action serves as a powerful tool to effortlessly create a functional Dataverse instance, enabling developers to run comprehensive tests and perform other critical tasks within their GitHub CI workflows. + +## Usage + +In order to use this action you need to add the following to your workflow file: + +```yaml +name: Test Dataverse +uses: gdcc/dataverse-action@main +with: + create-dv: true +``` + +### Parameters + +* `create-dv`: Whether to create a Dataverse to add data to or not. Default: `true` +* `port`: The port to run the Dataverse instance on. Default: `8080` + +## License + +This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details. \ No newline at end of file diff --git a/action.yml b/action.yml new file mode 100644 index 0000000..45234db --- /dev/null +++ b/action.yml @@ -0,0 +1,25 @@ +name: dv-configbaker +description: | + "This GitHub Action serves as a powerful tool to create a functional Dataverse instance, enabling developers to run tests and perform other critical tasks within their GitHub CI workflows." +inputs: + create-dv: + description: "Whether or not to create an example Dataverse" + required: true +runs: + using: "composite" + steps: + - name: "Checkout" + uses: "actions/checkout@v4" + - name: Setup Dataverse + run: ${{ github.action_path }}/scripts/dataverse_setup.sh + shell: bash + - name: Check API Status + run: ${{ github.action_path }}/scripts/check_api_status.sh + shell: bash + - name: Retrieve API Token + run: ${{ github.action_path }}/scripts/get_api_token.sh + shell: bash + - name: Create Dataverse + run: ${{ github.action_path }}/scripts/create_dataverse.sh + shell: bash + diff --git a/assets/dataverse-complete.json b/assets/dataverse-complete.json new file mode 100644 index 0000000..d5e92d1 --- /dev/null +++ b/assets/dataverse-complete.json @@ -0,0 +1,15 @@ +{ + "name": "Scientific Research", + "alias": "science", + "dataverseContacts": [ + { + "contactEmail": "pi@example.edu" + }, + { + "contactEmail": "student@example.edu" + } + ], + "affiliation": "Scientific Research University", + "description": "We do all the science.", + "dataverseType": "LABORATORY" +} diff --git a/assets/user.json b/assets/user.json new file mode 100644 index 0000000..358a59f --- /dev/null +++ b/assets/user.json @@ -0,0 +1,8 @@ +{ + "firstName": "Lisa", + "lastName": "Simpson", + "userName": "lsimpson", + "affiliation": "Springfield", + "position": "Student", + "email": "lsimpson@mailinator.com" + } \ No newline at end of file diff --git a/docker-compose-dataverse.yml b/docker-compose-dataverse.yml new file mode 100644 index 0000000..5df2ef3 --- /dev/null +++ b/docker-compose-dataverse.yml @@ -0,0 +1,104 @@ +version: '2.4' + +services: + dataverse: + container_name: 'dataverse' + hostname: dataverse + image: gdcc/dataverse:alpha + restart: on-failure + user: payara + environment: + - DATAVERSE_DB_HOST=postgres + - DATAVERSE_DB_PASSWORD=secret + - DATAVERSE_DB_USER=${DATAVERSE_DB_USER} + # to get HarvestingServerIT to pass + - dataverse_oai_server_maxidentifiers=2 + - dataverse_oai_server_maxrecords=2 + ports: + - '8080:8080' + networks: + - dataverse + depends_on: + - postgres + - solr + tmpfs: + - /dumps:mode=770,size=2052M,uid=1000,gid=1000 + - /tmp:mode=770,size=2052M,uid=1000,gid=1000 + mem_limit: 2147483648 # 2 GiB + mem_reservation: 1024m + privileged: false + + dataverse_bootstrap: + container_name: 'dataverse_bootstrap' + image: gdcc/configbaker:alpha + restart: 'no' + environment: + - TIMEOUT=${DATAVERSE_BOOTSTRAP_TIMEOUT} + command: + - bootstrap.sh + - dev + networks: + - dataverse + + postgres: + container_name: 'postgres' + hostname: postgres + image: postgres:${POSTGRES_VERSION} + restart: on-failure + environment: + - POSTGRES_USER=${DATAVERSE_DB_USER} + - POSTGRES_PASSWORD=secret + ports: + - '5432:5432' + networks: + - dataverse + + solr_initializer: + container_name: 'solr_initializer' + image: gdcc/configbaker:alpha + restart: 'no' + command: + - sh + - -c + - 'fix-fs-perms.sh solr && cp -a /template/* /solr-template' + volumes: + - ${RUNNER_TEMP}/solr/data:/var/solr + - ${RUNNER_TEMP}/solr/conf:/solr-template + + solr: + container_name: 'solr' + hostname: 'solr' + image: solr:${SOLR_VERSION} + depends_on: + - solr_initializer + restart: on-failure + ports: + - '8983:8983' + networks: + - dataverse + command: + - 'solr-precreate' + - 'collection1' + - '/template' + volumes: + - ${RUNNER_TEMP}/solr/data:/var/solr + - ${RUNNER_TEMP}/solr/conf:/template + + smtp: + container_name: 'smtp' + hostname: 'smtp' + image: maildev/maildev:2.0.5 + restart: on-failure + expose: + - '25' # smtp server + environment: + - MAILDEV_SMTP_PORT=25 + - MAILDEV_MAIL_DIRECTORY=/mail + networks: + - dataverse + tmpfs: + - /mail:mode=770,size=128M,uid=1000,gid=1000 + +networks: + dataverse: + driver: bridge diff --git a/scripts/check_api_status.sh b/scripts/check_api_status.sh new file mode 100755 index 0000000..f9391cd --- /dev/null +++ b/scripts/check_api_status.sh @@ -0,0 +1,7 @@ +echo "🚀 Health checks" + +./scripts/wait_for_url.sh \ + "http://localhost:8080/api/info/version" \ + "http://localhost:8080/api/metadatablocks" + +echo -e "✅ Health checks done\n" diff --git a/scripts/create_dataverse.sh b/scripts/create_dataverse.sh new file mode 100755 index 0000000..4eda682 --- /dev/null +++ b/scripts/create_dataverse.sh @@ -0,0 +1,6 @@ +echo "🚀 Creating Test Dataverse" + +curl -H "X-Dataverse-key:$API_TOKEN" \ + --silent \ + -X POST "localhost:8080/api/dataverses/1" \ + --upload-file ./assets/dataverse-complete.json diff --git a/scripts/dataverse_setup.sh b/scripts/dataverse_setup.sh new file mode 100755 index 0000000..4dead44 --- /dev/null +++ b/scripts/dataverse_setup.sh @@ -0,0 +1,18 @@ +#!/bin/bash + +echo "🚀 Setting up Dataverse" + +# Create host address +export HOST="http://localhost:8080" + +# Clone the dataverse repository and cd into it +git clone -b develop https://github.com/IQSS/dataverse.git + +cd dataverse + +# Run API containers +docker compose -f ../docker-compose-dataverse.yml \ + --env-file ../.env.dataverse \ + up -d --quiet-pull && echo -e "✅ Dataverse containers are up\n" + +cd ../ diff --git a/scripts/get_api_token.sh b/scripts/get_api_token.sh new file mode 100755 index 0000000..21b5db3 --- /dev/null +++ b/scripts/get_api_token.sh @@ -0,0 +1,30 @@ +#!/bin/bash + +echo "🚀 Retrieving API Token" + +# Set variables +export BUILTIN_USERS_KEY="burrito" +export PASSWORD="TEST123!" +export HOST="http://localhost:8080" + +# Set the builtin user key +curl -X PUT \ + -o /dev/null \ + -d $BUILTIN_USERS_KEY \ + --silent \ + $HOST/api/admin/settings/BuiltinUsers.KEY && + echo "├─ BuiltinUsers.KEY set" + +# Create a user and receive the API Token +curl -d @./assets/user.json \ + -o ./user_data.json \ + -H "Content-type:application/json" \ + --silent \ + "$HOST/api/builtin-users?password=$PASSWORD*&key=$BUILTIN_USERS_KEY" && + echo "├─ User created" + +# Retrieve the API Token and put into env variable +API_TOKEN=$(echo $(cat ./user_data.json) | jq -r '.data.apiToken') +echo "API_TOKEN=$API_TOKEN" >>$GITHUB_ENV + +echo -e "✅ API Token added to environment\n" diff --git a/scripts/wait_for_url.sh b/scripts/wait_for_url.sh new file mode 100755 index 0000000..c094556 --- /dev/null +++ b/scripts/wait_for_url.sh @@ -0,0 +1,33 @@ +#!/bin/bash + +############################################################################################## +# +# Credits: https://gist.github.com/eisenreich/195ab1f05715ec86e300f75d007d711c +# +# Wait for URLs until return HTTP 200 +# +# - Just pass as many urls as required to the script - the script will wait for each, one by one +# +# Example: ./wait_for_urls.sh "${MY_VARIABLE}" "http://192.168.56.101:8080" +############################################################################################## + +wait-for-url() { + echo -e "├─ Waiting for ${1}" + timeout --foreground -s TERM 280s bash -c \ + 'while [[ "$(curl -s -o /dev/null -m 3 -L -w ''%{http_code}'' ${0})" != "200" ]];\ + do sleep 20;\ + done' ${1} + local TIMEOUT_RETURN="$?" + if [[ "${TIMEOUT_RETURN}" == 0 ]]; then + echo -e "├─ Endpoint is up" + return + elif [[ "${TIMEOUT_RETURN}" == 120000 ]]; then + echo "├─ Timeout: ${1} -> EXIT" + exit "${TIMEOUT_RETURN}" + fi + +} + +for var in "$@"; do + wait-for-url "$var" +done