Skip to content

Merge pull request #49 from DevOps-Group-B/Linting #37

Merge pull request #49 from DevOps-Group-B/Linting

Merge pull request #49 from DevOps-Group-B/Linting #37

Workflow file for this run

# --- PIPELINE SUMMARY ---
# 1. Trigger: Runs automatically on a push to the 'main' branch or manually via workflow_dispatch.
# 2. Build & Test: Checks out code, sets up .NET, restores, and builds the project.
# Installs Playwright dependencies and runs all Unit, Integration, and E2E tests.
# If any test fails, the pipeline halts immediately to protect the production server.
# 3. Docker Image: If tests pass, it logs into Docker Hub, builds a new image using the GitHub run
# number as a tag (e.g., :45), and pushes it to the registry.
# 4. Deployment: Connects to the DigitalOcean droplet via SSH, pulls the new image, and swaps containers.
# It mounts a Managed Docker Volume and passes the DB path as an environment variable so the
# simulator's registered users and cheeps survive the deployment.
name: CI_CD
on:
push:
branches: [ "main" ]
workflow_dispatch:
permissions:
contents: read
env:
IMAGE_NAME: minitwitimage
CONTAINER_NAME: minitwit
APP_PORT: "5273"
HOST_PORT: "80"
jobs:
build_test_and_deploy:
runs-on: ubuntu-latest
steps:
# --- STAGE 1: SETUP ---
- name: Checkout
uses: actions/checkout@v4
- name: Setup .NET
uses: actions/setup-dotnet@v4
with:
dotnet-version: "9.0.x"
# --- STAGE 2: BUILD & TEST ---
- name: Restore dependencies
working-directory: itu-minitwit
run: dotnet restore
- name: C# Quality Gate (Format & Analyzers)
working-directory: itu-minitwit
run: |
dotnet format style --verify-no-changes
dotnet format analyzers --verify-no-changes
- name: Dockerfile Quality Gate (hadolint)
run: |
docker run --rm -i hadolint/hadolint < itu-minitwit/Dockerfile
docker run --rm -i hadolint/hadolint < itu-minitwit/monitoring/prometheus/Dockerfile
docker run --rm -i hadolint/hadolint < itu-minitwit/monitoring/grafana/Dockerfile
- name: Ansible Quality Gate (ansible-lint)
run: |
pipx install ansible
pipx inject ansible ansible-lint
ansible-galaxy collection install community.docker
ansible-lint ansible/playbook.yml
- name: Build project
working-directory: itu-minitwit
run: dotnet build --no-restore
# Playwright requires actual browser binaries to run E2E tests in the headless Ubuntu runner
- name: Install Playwright Browsers
working-directory: itu-minitwit
run: |
dotnet tool install --global Microsoft.Playwright.CLI
playwright install --with-deps chromium
# Run all tests. If this fails, the action STOPS here and will not deploy bad code.
- name: Test
working-directory: itu-minitwit
run: dotnet test --no-build --verbosity normal
# --- STAGE 3: DOCKER HUB PUBLISHING ---
# Everything below this line ONLY runs if all tests passed successfully!
- name: Docker login
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
# Builds the app image and tags it with both the unique GitHub run number and :latest
- name: Build and push app image
uses: docker/build-push-action@v6
with:
context: ./itu-minitwit
file: ./itu-minitwit/Dockerfile
push: true
tags: |
${{ secrets.DOCKERHUB_USERNAME }}/${{ env.IMAGE_NAME }}:${{ github.run_number }}
${{ secrets.DOCKERHUB_USERNAME }}/${{ env.IMAGE_NAME }}:latest
# Build and push Prometheus image
- name: Build and push Prometheus image
uses: docker/build-push-action@v6
with:
context: ./itu-minitwit/monitoring/prometheus
file: ./itu-minitwit/monitoring/prometheus/Dockerfile
push: true
tags: |
${{ secrets.DOCKERHUB_USERNAME }}/prometheus_image:latest
# Build and push Grafana image
- name: Build and push Grafana image
uses: docker/build-push-action@v6
with:
context: ./itu-minitwit/monitoring/grafana
file: ./itu-minitwit/monitoring/grafana/Dockerfile
push: true
tags: |
${{ secrets.DOCKERHUB_USERNAME }}/grafana_image:latest
# --- STAGE 4: SERVER DEPLOYMENT (via Ansible) ---
- name: Run Ansible Playbook
uses: dawidd6/action-ansible-playbook@v2
env:
DOCKERHUB_TOKEN: ${{ secrets.DOCKERHUB_TOKEN }}
with:
playbook: ansible/playbook.yml
directory: ./
inventory: |
[minitwit_servers]
server ansible_host=${{ secrets.SSH_HOST }} ansible_user=${{ secrets.SSH_USER }}
key: ${{ secrets.SSH_KEY }}
options: |
--extra-vars "dockerhub_username=${{ secrets.DOCKERHUB_USERNAME }} image_tag=${{ github.run_number }} POSTGRES_CONNECTION_STRING='${{ secrets.POSTGRES_CONNECTION_STRING }}'"