ci: add tests #131
Workflow file for this run
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |