Installing two neo4j servers (operating on different ports) via yml in GitHub action workflow

Viewed 132

how can I install two neo4j 3.5.x servers (operating on different ports) via yml in GitHub action workflow, give them custom username and password and activate them?

in addition, I need to compile my Java project with JDK 14.

My final (and finished) software engineering degree project

My full yml file so far:

# This workflow will build a Java project with Maven
# For more information see: https://help.github.com/actions/language-and-framework-guides/building-and-testing-java-with-maven

name: Java CI with Maven

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

jobs:
  build:

    runs-on: ubuntu-latest

    steps:
      - uses: actions/checkout@v2
      - name: Set up JDK 14
        uses: actions/setup-java@v1.3.0
        with:
          java-version: 14
      - name: setting testing environment 
        run: |
          wget -qO - https://www.mongodb.org/static/pgp/server-4.2.asc | sudo apt-key add -
          wget -O - https://debian.neo4j.com/neotechnology.gpg.key | sudo apt-key add -
          echo 'deb https://debian.neo4j.com stable 3.5' | sudo tee -a /etc/apt/sources.list.d/neo4j.list
          echo "deb [ arch=amd64,arm64 ] https://repo.mongodb.org/apt/ubuntu bionic/mongodb-org/4.2 multiverse" | sudo tee /etc/apt/sources.list.d/mongodb-org-4.2.list
          sudo add-apt-repository -y ppa:openjdk-r/ppa
          sudo apt-get update
          sudo apt-get install -y neo4j=1:3.5.19 mongodb-org
          sudo systemctl start mongod
          sudo systemctl status mongod
          sudo service neo4j start
          service neo4j-service status
          
      - name: Build with Maven
        run: mvn -B clean:clean compiler:compile source:jar assembly:single --file pom.xml
      - uses: "marvinpinto/action-automatic-releases@v1.0.0"
        with:
          repo_token: "${{ secrets.GITHUB_TOKEN }}"
          automatic_release_tag: "latest"
          prerelease: true
          title: "Development Build"
          files: |
            /home/runner/work/Model-based-Framework-for-Developing-Multi-Database-Application/Model-based-Framework-for-Developing-Multi-Database-Application/LICENSE.txt
            /home/runner/work/Model-based-Framework-for-Developing-Multi-Database-Application/Model-based-Framework-for-Developing-Multi-Database-Application/target/*.jar
1 Answers

I think the most convenient and fastest way to set up two neo4j instances listening on different ports will be using an official neo4j Docker image and two separate Docker containers listening on distinct ports. It can be done in GitHub Action workflow in the following way:

on:
  push:
    branches:
      - master
jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - name: neo4j-instance-1 setup (ports HTTP:17474, HTTPS:17473, BOLT:17687)
        run: |
          docker run --detach \
            --name neo4j-instance-1 \
            --env NEO4J_AUTH=none \
            --publish 17474:7474 \
            --publish 17473:7473 \
            --publish 17687:7687 \
            neo4j:3.5
      - name: neo4j-instance-2 setup (ports HTTP:27474, HTTPS:27473, BOLT:27687)
        run: |
          docker run --detach \
            --name neo4j-instance-2 \
            --env NEO4J_AUTH=none \
            --publish 27474:7474 \
            --publish 27473:7473 \
            --publish 27687:7687 \
            neo4j:3.5
      - name: Wait for neo4j-instance-1 to be ready
        timeout-minutes: 1
        run: (docker logs -f neo4j-instance-1 & ) | grep -q Started
      - name: Wait for neo4j-instance-2 to be ready
        timeout-minutes: 1
        run: (docker logs -f neo4j-instance-2 & ) | grep -q Started
      - name: Verify neo4j-instance-1 HTTP connectivity
        run: curl -sI http://localhost:17474
      - name: Verify neo4j-instance-1 HTTPS connectivity
        run: curl -ksI https://localhost:17473
      - name: Verify neo4j-instance-2 HTTP connectivity
        run: curl -sI http://localhost:27474
      - name: Verify neo4j-instance-2 HTTPS connectivity
        run: curl -ksI https://localhost:27473
      - name: [your next step]
...

The workflow setups two distinct neo4j instances listening on ports 17474, 17687 and 27474, 27687. You can utilise those instances later in following workflow steps by connecting to the particular ports. There's no authentication required as it's been disabled by setting NEO4J_AUTH=none environment variable.

EDIT

Answering questions from the comment:

And how can I decide the username & password in NEO4J_AUTH?

You can enable authentication and set the credentials by setting NEO4J_AUTH=<user>/<password>

Please refer to the original Neo4j documentation (§Run Docker with Neo4j) for the details.

There is a way to Wait for neo4j-instance dynamically i.e as soon the instance is ready, advance to the next stage? (should I just delete the &?)

docker run ... command exits immediately as the container is created but the neo4j instance running within the container requires some time to boot up until it's ready to accept incoming connection requests.

The line

(docker logs -f neo4j-instance-1 & ) | grep -q Started

is responsible to wait until Neo4j is started by simply tailing the container logs for a matching Started string. I don't understand why do you want to remove the &. It's required to run docker logs command in the background of the created sub-shell. If you remove it, it will break the pipe. Please refer to this post for more details.

how can I control the bolt, http, https ports?

The ports (HTTP, HTTPS and BOLT) are provided in the workflow above. Read it carefully and you will find it. You can adjust it according to your needs. I have updated the workflow to name the setup steps to explain all the ports. Take a look at the --publish flag. It's responsible for exposing the container ports to the runner. Please refer to (§Run Docker with Neo4j) for more details.

Related