Feature/CI Workflow (#1)
All checks were successful
Build and Publish Docker Image / Build and Validate (push) Successful in 6s
Build and Publish Docker Image / Publish to Registry (push) Successful in 6s

# Add CI/CD Pipeline with Docker Build and Publish

## Summary
This PR adds a complete CI/CD pipeline for building and publishing Docker images of the Three.js game to the Forgejo container registry. The workflow automatically builds, validates, and publishes Docker images with semantic versioning when code is merged to main.

## Changes

### 🚀 CI/CD Workflow (`.forgejo/workflows/ci.yaml`)
- **Build & Validation**: Automatically builds Docker image on PRs and validates it works
- **Semantic Versioning**: Auto-increments patch version on each merge to main
  - First version: `0.1.0` (when no tags exist)
  - Subsequent merges: Auto-increments patch (e.g., `0.1.0` → `0.1.1` → `0.1.2`)
- **Publishing**: Publishes images to `git.jusemon.com/jusemon/threejs-test:<version>` and `latest` tag
- **Git Tagging**: Automatically creates git tags (e.g., `v0.1.0`) for releases
- **Registry Integration**: Uses Forgejo container registry with secrets-based authentication

### 🐳 Docker Setup
- **Dockerfile**: Custom nginx:alpine image with the game HTML file
- **docker-compose.yml**: Simple orchestration for local development
- **nginx.conf**: Minimal nginx configuration with gzip compression

## Workflow Behavior

### On Pull Requests
-  Builds Docker image
-  Validates image by running container and checking HTTP response
-  Does NOT publish (validation only)

### On Merge to Main
-  Builds Docker image
-  Validates image
-  Publishes to registry with version tag
-  Tags as `latest`
-  Creates git tag for the release

## Required Setup

Before merging, ensure these secrets are configured in the repository:
- `REGISTRY_USERNAME`: Forgejo username
- `REGISTRY_PASSWORD`: Personal Access Token with package write permissions

## Versioning Strategy

- **First Release**: `0.1.0` (when no tags exist)
- **Subsequent Releases**: Auto-increments patch version on each merge
- **Image Tags**:
  - `git.jusemon.com/jusemon/threejs-test:0.1.0`
  - `git.jusemon.com/jusemon/threejs-test:latest` (always points to latest main)

## Testing

The workflow includes validation steps that:
1. Build the Docker image
2. Run a test container
3. Verify the web server responds correctly
4. Only publish if all validations pass

## Benefits

-  Automated builds and deployments
-  Consistent versioning
-  Image validation before publishing
-  Easy rollback using version tags
-  Latest tag for easy deployment

Reviewed-on: #1
Co-authored-by: Juan Sebastian Montoya <juansmm@outlook.com>
Co-committed-by: Juan Sebastian Montoya <juansmm@outlook.com>
This commit is contained in:
Juan Sebastián Montoya 2025-11-25 17:21:46 -05:00 committed by Juan Sebastián Montoya
parent fc24028ed9
commit b21a0e3a39
4 changed files with 135 additions and 0 deletions

100
.forgejo/workflows/ci.yaml Normal file
View file

@ -0,0 +1,100 @@
name: Build and Publish Docker Image
on:
pull_request:
branches:
- main
push:
branches:
- main
jobs:
build-and-validate:
name: Build and Validate
runs-on: ubuntu
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Build Docker Image
run: |
docker build -t threejs-test:test .
- name: Validate Image
run: |
docker run --rm -d --name test-container -p 8080:80 threejs-test:test
sleep 2
curl -f http://localhost:8080 || exit 1
docker stop test-container
publish:
name: Publish to Registry
runs-on: ubuntu
needs: build-and-validate
if: github.event_name == 'push' || gitea.event_name == 'push'
steps:
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 0 # Fetch all history for tags
- name: Login to Registry
run: |
echo "${{ secrets.REGISTRY_PASSWORD }}" | docker login git.jusemon.com -u "${{ secrets.REGISTRY_USERNAME }}" --password-stdin
- name: Determine Version
id: version
run: |
# Get latest version tag
LATEST_TAG=$(git describe --tags --match 'v*.*.*' --abbrev=0 2>/dev/null || echo "v0.0.0")
LATEST_VERSION="${LATEST_TAG#v}"
# Parse version components
IFS='.' read -r MAJOR MINOR PATCH <<< "$LATEST_VERSION"
MAJOR=${MAJOR:-0}
MINOR=${MINOR:-0}
PATCH=${PATCH:-0}
# Increment patch version for each merge to main, or start at 0.1.0 if no tags exist
if [[ "$LATEST_TAG" == "v0.0.0" ]]; then
# First version
NEW_VERSION="0.1.0"
else
# Increment patch version for each merge to main
PATCH=$((PATCH + 1))
NEW_VERSION="$MAJOR.$MINOR.$PATCH"
fi
echo "version=$NEW_VERSION" >> $GITHUB_OUTPUT
echo "tag=v$NEW_VERSION" >> $GITHUB_OUTPUT
echo "Latest tag: $LATEST_TAG"
echo "New version: $NEW_VERSION"
- name: Build Docker Image
run: |
IMAGE_NAME="git.jusemon.com/jusemon/threejs-test:${{ steps.version.outputs.version }}"
docker build -t "$IMAGE_NAME" .
echo "IMAGE_NAME=$IMAGE_NAME" >> $GITHUB_ENV
- name: Push Docker Image
run: |
IMAGE_NAME="git.jusemon.com/jusemon/threejs-test:${{ steps.version.outputs.version }}"
docker push "$IMAGE_NAME"
# Also tag as 'latest' for main branch
docker tag "$IMAGE_NAME" "git.jusemon.com/jusemon/threejs-test:latest"
docker push "git.jusemon.com/jusemon/threejs-test:latest"
- name: Create Git Tag
run: |
git config user.name "forgejo-actions"
git config user.email "forgejo-actions@forgejo.io"
TAG="${{ steps.version.outputs.tag }}"
# Check if tag already exists
if git rev-parse "$TAG" >/dev/null 2>&1; then
echo "Tag $TAG already exists, skipping tag creation"
else
git tag -a "$TAG" -m "Release ${{ steps.version.outputs.version }}"
git push origin "$TAG"
fi