# CI/CD Workflows This repository includes automated CI/CD workflows for building, testing, and deploying the CodeSnippet application. ## Workflows ### 1. Docker Build and Push to GHCR (`docker-publish.yml`) This workflow automatically builds **two separate Docker images** (backend and frontend) and pushes them to GitHub Container Registry (GHCR). **Triggers:** - Push to `main` branch - Push of version tags (e.g., `v1.0.0`) - Pull requests to `main` (build only, no push) **Features:** - Two clearly marked build jobs: - **Backend**: Python/Flask API (`ghcr.io//-backend`) - **Frontend**: React/Vite application (`ghcr.io//-frontend`) - Multi-platform Docker image building (AMD64 and ARM64) - Automatic tagging strategy: - `latest` - Latest build from main branch - `v1.0.0` - Semantic version tags - `v1.0` - Major.minor version - `v1` - Major version - `main-` - Branch with commit SHA - Separate Docker layer caching for each image - Parallel builds for faster CI/CD **Configuration:** - The workflow uses the `GITHUB_TOKEN` for authentication (automatic) - Optional: Set `VITE_FLASK_BACKEND_URL` as a repository variable for frontend backend configuration **Using the Docker Images:** ```bash # Backend - Pull and run docker pull ghcr.io//-backend:latest docker run -p 5000:5000 ghcr.io//-backend:latest # Frontend - Pull and run docker pull ghcr.io//-frontend:latest docker run -p 3000:3000 ghcr.io//-frontend:latest # Pull specific versions docker pull ghcr.io//-backend:v1.0.0 docker pull ghcr.io//-frontend:v1.0.0 # Pull for a specific architecture (optional) docker pull --platform linux/amd64 ghcr.io//-backend:latest docker pull --platform linux/arm64 ghcr.io//-frontend:latest # Run full stack with docker-compose # Create a docker-compose.yml referencing GHCR images: # backend: # image: ghcr.io//-backend:latest # frontend: # image: ghcr.io//-frontend:latest ``` **Making Images Public:** 1. Go to your packages at `https://github.com/users//packages` 2. For each image (`-backend` and `-frontend`): - Click on the package - Go to "Package settings" - Change visibility to "Public" if you want the image to be publicly accessible ### 2. Deploy to GitHub Pages (`deploy-pages.yml`) This workflow builds the frontend application and deploys it to GitHub Pages. **Triggers:** - Push to `main` branch - Manual trigger via workflow dispatch **Features:** - Automatic build using Node.js 20 and npm - Uploads build artifacts to GitHub Pages - Automatic deployment to `https://.github.io//` **Setup Requirements:** 1. **Enable GitHub Pages:** - Go to repository Settings → Pages - Under "Build and deployment", select "Source: GitHub Actions" 2. **Configure Base Path:** Set the `VITE_BASE_PATH` repository variable for proper asset loading: - For deployment at `https://.github.io//`, set: `//` - For custom domain or root deployment, set: `/` Go to Settings → Secrets and variables → Actions → Variables → New repository variable - Name: `VITE_BASE_PATH` - Value: `//` (or your repository name) 3. **Optional Configuration:** - Set `VITE_FLASK_BACKEND_URL` as a repository variable if you want to connect to a backend **Accessing the Deployed Site:** After the workflow runs successfully, your site will be available at: - `https://.github.io//` - The URL is also shown in the workflow run details ## Configuration ### Repository Variables Set these variables in your repository settings (Settings → Secrets and variables → Actions → Variables): - `VITE_BASE_PATH` (recommended for GitHub Pages): Base path for the application - Example: `//` for `username.github.io//` - Use `/` for custom domains or root deployment - `VITE_FLASK_BACKEND_URL` (optional): URL of your Flask backend API - Example: `https://api.example.com` - If not set, the app will use local IndexedDB storage ### Repository Secrets The workflows use the following automatically available secrets: - `GITHUB_TOKEN`: Automatically provided by GitHub Actions (no setup needed) ## Workflow Permissions Both workflows require the following permissions (already configured): **docker-publish.yml:** - `contents: read` - Read repository contents - `packages: write` - Push to GitHub Container Registry (for both backend and frontend images) - `id-token: write` - OIDC token for security **deploy-pages.yml:** - `contents: read` - Read repository contents - `pages: write` - Deploy to GitHub Pages - `id-token: write` - OIDC token for security ## Manual Triggering ### GitHub Pages Deployment You can manually trigger the GitHub Pages deployment: 1. Go to Actions tab 2. Select "Deploy to GitHub Pages" workflow 3. Click "Run workflow" 4. Select the branch and click "Run workflow" ### Creating a Release To trigger a Docker build with version tags: ```bash # Create and push a version tag git tag v1.0.0 git push origin v1.0.0 ``` This will build and push the Docker image with tags: `v1.0.0`, `v1.0`, `v1`, and `latest`. ## Troubleshooting ### Docker Build Fails 1. Check the build logs in the Actions tab 2. Ensure the Dockerfile is valid 3. Test the build locally: `docker build -t test .` 4. For multi-arch builds locally, use: `docker buildx build --platform linux/amd64,linux/arm64 -t test .` ### GitHub Pages Deployment Fails 1. Ensure GitHub Pages is enabled in repository settings 2. Check that the build completes successfully 3. Verify the `dist` folder is created during build 4. Check workflow permissions are correctly set ### Image Not Pushing to GHCR 1. Verify workflow permissions include `packages: write` 2. Check that the workflow is running on push to main (not a PR) 3. Ensure the repository owner has enabled GHCR ## Local Development To test the workflows locally, you can: 1. **Build the Backend Docker image:** ```bash cd backend docker build -t -backend . docker run -p 5000:5000 -backend ``` 2. **Build the Frontend Docker image:** ```bash docker build -t -frontend . docker run -p 3000:3000 -frontend ``` 3. **Build for multiple architectures (requires Docker Buildx):** ```bash # Create a new builder instance (one-time setup) docker buildx create --use # Build backend for both AMD64 and ARM64 docker buildx build --platform linux/amd64,linux/arm64 -t -backend ./backend # Build frontend for both AMD64 and ARM64 docker buildx build --platform linux/amd64,linux/arm64 -t -frontend . # Build and load for your current architecture docker buildx build --platform linux/amd64 -t -backend --load ./backend docker buildx build --platform linux/amd64 -t -frontend --load . ``` 4. **Build for GitHub Pages:** ```bash npm ci npm run build # Serve the dist folder npx serve dist ``` ## Workflow Status Badges Add these badges to your README.md (replace `` and `` with your values): ```markdown [![Docker Build](https://github.com///actions/workflows/docker-publish.yml/badge.svg)](https://github.com///actions/workflows/docker-publish.yml) [![Deploy to Pages](https://github.com///actions/workflows/deploy-pages.yml/badge.svg)](https://github.com///actions/workflows/deploy-pages.yml) ``` ## Further Customization ### Adding Tests To add automated testing before deployment, modify the workflows to include a test step: ```yaml - name: Run tests run: npm test ``` ### Multi-stage Deployments For staging and production environments, consider: - Creating separate workflows for different branches - Using environment protection rules - Configuring different backend URLs per environment ### Backend Deployment The workflow now includes automated backend deployment to GHCR: - Backend image is automatically built from the `/backend` directory - Image is available at `ghcr.io//-backend` - Deploy backend to a service like Heroku, DigitalOcean, or AWS using the GHCR image - Update `VITE_FLASK_BACKEND_URL` to point to your deployed backend