Skip to content

ci: add tests

ci: add tests #131

Workflow file for this run

name: Deployement Tests
on:
push:
branches:
- "*"
pull_request:
types: [opened, synchronize]
branches:
- "*"
env:
IMAGE_BASE_PATH: "./tests/host/Dockerfile"
IMAGE_BASE_NAME: "ghcr.io/tristiisch/docker_throw_ssh"
IMAGE_FINAL_PATH: "./tests/host/with_key/Dockerfile"
IMAGE_FINAL_CONTEXT: "./tests/host/with_key"
IMAGE_FINAL_NAME: "ghcr.io/tristiisch/docker_throw_ssh_with_key"
IMAGE_FINAL_TAR: "docker_throw_ssh_with_key.tar"
IMAGE_FINAL_TAR_PATH: "./docker_throw_ssh_with_key.tar"
IMAGE_FINAL_ARTIFACT_NAME: "docker-throw-ssh"
SSH_KEY_TYPE: "ed25519"
SSH_KEY_PRIVATE_PATH: "/tmp/ssh/id_ed25519"
SSH_KEY_PUBLIC_PATH: "/tmp/ssh/id_ed25519.pub"
SSH_ACCOUNT_NAME: "deploy"
TEST_CONTAINER_NAME: "docker_throw_ssh"
TEST_SSH_HOST: "localhost"
TEST_SSH_PORT: "2222"
CONTAINER_PORT: "22"
jobs:
utils:
runs-on: ubuntu-latest
name: "Utils"
outputs:
short_sha: ${{ steps.short_sha.outputs.value }}
steps:
- name: Retrieve short SHA
id: short_sha
run: |
SHA="${{ github.sha }}"
SHORT_SHA="${SHA:0:7}"
echo "value=$SHORT_SHA" >> $GITHUB_OUTPUT
echo "Output :"
cat $GITHUB_OUTPUT
generate_key:
runs-on: ubuntu-latest
name: "Generate SSH Key"
outputs:
public_key: ${{ steps.ssh_key_public.outputs.value }}
private_key: ${{ steps.ssh_key_private.outputs.value }}
steps:
- name: Create directory for SSH key
run: |
mkdir -p "$(dirname ${{ env.SSH_KEY_PRIVATE_PATH }})"
- name: Generate SSH key pair
run: |
ssh-keygen -t "${{ env.SSH_KEY_TYPE }}" -f "${{ env.SSH_KEY_PRIVATE_PATH }}" -N "" -o -a 100
- name: Retrieve public key
id: ssh_key_public
run: |
EOF=$(dd if=/dev/urandom bs=15 count=1 status=none | base64)
echo "value<<$EOF" >> $GITHUB_OUTPUT
cat ${{ env.SSH_KEY_PUBLIC_PATH }} >> $GITHUB_OUTPUT
echo "$EOF" >> $GITHUB_OUTPUT
echo "Output :"
cat $GITHUB_OUTPUT
- name: Retrieve private key
id: ssh_key_private
run: |
EOF=$(dd if=/dev/urandom bs=15 count=1 status=none | base64)
echo "private<<$EOF" >> $GITHUB_OUTPUT
cat ${{ env.SSH_KEY_PRIVATE_PATH }} >> $GITHUB_OUTPUT
echo "$EOF" >> $GITHUB_OUTPUT
echo "Output :"
cat $GITHUB_OUTPUT
build_base_service:
runs-on: ubuntu-latest
name: "Build base service"
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 1
- name: Login to Github Container Registry
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Docker meta
id: meta
uses: docker/metadata-action@v5
with:
images: ${{ env.IMAGE_BASE_NAME }}
tags: |
type=sha,priority=100,prefix=test-,suffix=,format=short
type=raw,value=latest,enable={{is_default_branch}}
- name: Build initial Docker image for SSHD service in DinD
uses: docker/build-push-action@v6
with:
file: ${{ env.IMAGE_BASE_PATH }}
context: .
tags: ${{ steps.meta.outputs.tags }}
cache-from: type=gha
cache-to: type=gha,mode=max
push: true
build_run_test_service:
runs-on: ubuntu-latest
name: "Build test service"
needs: ["utils", "generate_key", "build_base_service"]
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 1
- name: Login to Github Container Registry
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Docker meta
id: meta
uses: docker/metadata-action@v5
with:
images: ${{ env.IMAGE_FINAL_NAME }}
tags: |
type=sha,priority=100,prefix=test-,suffix=,format=short
type=raw,value=latest,enable={{is_default_branch}}
- name: Build test Docker image for SSHD service in DinD
uses: docker/build-push-action@v6
with:
file: ${{ env.IMAGE_FINAL_PATH }}
context: ${{ env.IMAGE_FINAL_CONTEXT }}
tags: ${{ steps.meta.outputs.tags }}
cache-from: type=gha
cache-to: type=gha,mode=max
build-args: |
BASE_TAG=test-${{ needs.utils.outputs.short_sha }}
SSH_ACCOUNT=${{ env.SSH_ACCOUNT_NAME }}
SSH_PUBLIC_KEY=${{ needs.generate_key.outputs.public_key }}
push: true
# load: true
# - name: Export image
# run: docker save "${{ env.IMAGE_FINAL_NAME }}:${{ github.sha }}" -o "${{ env.IMAGE_FINAL_TAR_PATH }}"
# - name: Upload image as artifact
# uses: actions/upload-artifact@v4
# with:
# name: ${{ env.IMAGE_FINAL_ARTIFACT_NAME }}
# path: "${{ env.IMAGE_FINAL_TAR_PATH }}"
# if-no-files-found: error
# retention-days: 1
run_test_service:
runs-on: ubuntu-latest
name: "Test service"
needs: ["utils", "generate_key", "build_run_test_service"]
outputs:
ssh_server_public_key: ${{ steps.get_ssh_public_key.outputs.value }}
steps:
# - name: Download image
# uses: actions/download-artifact@v4
# with:
# name: ${{ env.IMAGE_FINAL_ARTIFACT_NAME }}
# - name: Load Docker image
# run: docker load -i "${{ env.IMAGE_FINAL_TAR_PATH }}"
- name: Start test Docker container
run: |
docker run \
--detach \
-p 2222:22 \
--name ${{ env.TEST_CONTAINER_NAME}} \
--privileged \
--tty \
-v /sys/fs/cgroup:/sys/fs/cgroup \
--cgroupns=host \
--cap-add=NET_ADMIN \
--cap-add=NET_RAW \
--cap-add=SYS_ADMIN \
--tmpfs /run \
--tmpfs /run/lock \
--tmpfs /tmp \
"${{ env.IMAGE_FINAL_NAME }}:test-${{ needs.utils.outputs.short_sha }}"
- name: Retrieve container IP
id: container_ip
run: |
IP=docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}'
echo "value=$IP" >> $GITHUB_OUTPUT
- name: Verify SSH server availability at ${{ steps.container_ip.outputs.value }}:${{ env.TEST_SSH_PORT }}
run: |
timeout 30 bash -c 'until nc -zv ${{ steps.container_ip.outputs.value }} ${{ env.TEST_SSH_PORT }}; do sleep 1; done'
BANNER=$(echo QUIT | nc -w5 ${{ steps.container_ip.outputs.value }} ${{ env.TEST_SSH_PORT }} 2>/dev/null)
[[ $BANNER == SSH-* ]] && echo "SSH server is available: $BANNER" || (echo "No SSH server found or invalid banner: $BANNER" && exit 1)
- name: Save generated private SSH key to file
run: |
EOF=$(dd if=/dev/urandom bs=15 count=1 status=none | base64)
cat << $EOF > ${{ env.SSH_KEY_PRIVATE_PATH }}
${{ needs.generate_key.outputs.private_key }}
$EOF
- name: Run SSH connection test and retrieve Docker info
run: |
ssh -v -i "${{ env.SSH_KEY_PRIVATE_PATH }}" -o 'UserKnownHostsFile=/dev/null' -o 'StrictHostKeyChecking=no' \
-p "${{ env.TEST_SSH_PORT }}" "${{ env.SSH_ACCOUNT_NAME }}@${{ steps.container_ip.outputs.value }}" docker info
- name: Extract SSH server public key
id: get_ssh_public_key
run: |
PUBLIC_KEY=$(ssh-keyscan -t ${{ env.SSH_KEY_TYPE }} -p ${{ env.TEST_SSH_PORT }} ${{ steps.container_ip.outputs.value }})
echo "value=$(echo $PUBLIC_KEY | cut -d' ' -f2-)" >> $GITHUB_OUTPUT
echo "Output :"
cat $GITHUB_OUTPUT
- name: Save SSH server public key to temporary known_hosts file
run: |
EOF=$(dd if=/dev/urandom bs=15 count=1 status=none | base64)
cat << $EOF > /tmp/known_hosts_temp
${{ steps.get_ssh_public_key.outputs.value }}
$EOF
- name: Run SSH test with strict host key checking
run: |
ssh -v -i "${{ env.SSH_KEY_PRIVATE_PATH }}" -o 'UserKnownHostsFile=/tmp/known_hosts_temp' -o 'StrictHostKeyChecking=strict' \
-p "${{ env.TEST_SSH_PORT }}" "${{ env.SSH_ACCOUNT_NAME }}@${{ steps.container_ip.outputs.value }}" docker info
- name: Stop test Docker container
run: docker stop ${{ env.TEST_CONTAINER_NAME}}
- name: Remove test Docker container and associated volumes
run: docker rm -v ${{ env.TEST_CONTAINER_NAME}}
test1:
runs-on: ubuntu-latest
name: "Basic"
needs: ["utils", "generate_key", "build_run_test_service", "run_test_service"]
services:
docker-throw-ssh:
image: "ghcr.io/tristiisch/docker_throw_ssh:test-${{ needs.utils.outputs.short_sha }}"
ports:
- 2222:22
options: >
--privileged
--tty
-v /sys/fs/cgroup:/sys/fs/cgroup
--cgroupns=host
--cap-add=NET_ADMIN
--cap-add=NET_RAW
--cap-add=SYS_ADMIN
--tmpfs /run
--tmpfs /run/lock
--tmpfs /tmp
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 1
- uses: ./.github/workflows/setup
- name: Start Deployment 1 - Basic
uses: ./
with:
deployment_mode: docker-swarm
remote_docker_host: "docker-throw-ssh"
remote_docker_port: "${{ env.CONTAINER_PORT }}"
remote_docker_username: "${{ env.SSH_ACCOUNT_NAME }}"
ssh_private_key: "${{ needs.generate_key.outputs.private_key }}"
ssh_public_key: "${{ needs.run_test_service.outputs.ssh_server_public_key }}"
stack_file_path: ./tests/docker-compose.yml
stack_name: nginx_1
test2:
runs-on: ubuntu-latest
name: "No pub key"
needs: ["utils", "generate_key", "build_run_test_service", "run_test_service"]
services:
docker-throw-ssh:
image: "ghcr.io/tristiisch/docker_throw_ssh:test-${{ needs.utils.outputs.short_sha }}"
ports:
- 2222:22
options: >
--privileged
--tty
-v /sys/fs/cgroup:/sys/fs/cgroup
--cgroupns=host
--cap-add=NET_ADMIN
--cap-add=NET_RAW
--cap-add=SYS_ADMIN
--tmpfs /run
--tmpfs /run/lock
--tmpfs /tmp
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 1
- uses: ./.github/workflows/setup
- name: Start Deployment 2 - No pub key
uses: ./
with:
deployment_mode: docker-swarm
remote_docker_host: "docker-throw-ssh"
remote_docker_port: "${{ env.CONTAINER_PORT }}"
remote_docker_username: "${{ env.SSH_ACCOUNT_NAME }}"
ssh_private_key: "${{ needs.generate_key.outputs.private_key }}"
stack_file_path: ./tests/docker-compose.yml
stack_name: nginx_2
test3:
runs-on: ubuntu-latest
name: "Background deploy"
needs: ["utils", "generate_key", "build_run_test_service", "run_test_service"]
services:
docker-throw-ssh:
image: "ghcr.io/tristiisch/docker_throw_ssh:test-${{ needs.utils.outputs.short_sha }}"
ports:
- 2222:22
options: >
--privileged
--tty
-v /sys/fs/cgroup:/sys/fs/cgroup
--cgroupns=host
--cap-add=NET_ADMIN
--cap-add=NET_RAW
--cap-add=SYS_ADMIN
--tmpfs /run
--tmpfs /run/lock
--tmpfs /tmp
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 1
- uses: ./.github/workflows/setup
- name: Start Deployment 3 - Background deploy
uses: ./
with:
deployment_mode: docker-swarm
remote_docker_host: "docker-throw-ssh"
remote_docker_port: "${{ env.CONTAINER_PORT }}"
remote_docker_username: "${{ env.SSH_ACCOUNT_NAME }}"
ssh_private_key: "${{ needs.generate_key.outputs.private_key }}"
ssh_public_key: "${{ needs.run_test_service.outputs.ssh_server_public_key }}"
stack_file_path: ./tests/docker-compose.yml
stack_name: nginx_3
deploy_foreground: false
test4:
runs-on: ubuntu-latest
name: "Debug"
needs: ["utils", "generate_key", "build_run_test_service", "run_test_service"]
services:
docker-throw-ssh:
image: "ghcr.io/tristiisch/docker_throw_ssh:test-${{ needs.utils.outputs.short_sha }}"
ports:
- 2222:22
options: >
--privileged
--tty
-v /sys/fs/cgroup:/sys/fs/cgroup
--cgroupns=host
--cap-add=NET_ADMIN
--cap-add=NET_RAW
--cap-add=SYS_ADMIN
--tmpfs /run
--tmpfs /run/lock
--tmpfs /tmp
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 1
- uses: ./.github/workflows/setup
- name: Start Deployment 4 - Debug
uses: ./
with:
deployment_mode: docker-swarm
remote_docker_host: "docker-throw-ssh"
remote_docker_port: "${{ env.CONTAINER_PORT }}"
remote_docker_username: "${{ env.SSH_ACCOUNT_NAME }}"
ssh_private_key: "${{ needs.generate_key.outputs.private_key }}"
ssh_public_key: "${{ needs.run_test_service.outputs.ssh_server_public_key }}"
stack_file_path: ./tests/docker-compose.yml
stack_name: nginx_4
debug: true