Files
TimeTracker/.github/workflows/docker-publish.yml
T
2025-09-03 11:05:10 +02:00

223 lines
8.1 KiB
YAML

name: Build and Publish TimeTracker Docker Image
on:
push:
branches: [ main ]
tags: [ 'v*' ]
pull_request:
branches: [ main ]
release:
types: [ published ]
workflow_dispatch:
inputs:
version:
description: 'Custom version tag (e.g., v1.2.3, build-123)'
required: false
default: ''
env:
REGISTRY: ghcr.io
IMAGE_NAME: drytrix/timetracker
jobs:
build:
runs-on: ubuntu-latest
permissions:
contents: read
packages: write
strategy:
matrix:
include:
- name: amd64
platform: linux/amd64
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
fetch-depth: 0 # Fetch full history for better versioning
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Log in to Container Registry
if: github.event_name != 'pull_request'
uses: docker/login-action@v3
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Determine version
id: version
run: |
# Version determination per requirement:
# - If a version tag is available, use that (release tag or git tag)
# - Otherwise use dev-{buildnumber}
if [[ "${{ github.event.inputs.version }}" != "" ]]; then
VERSION="${{ github.event.inputs.version }}"
VERSION_SOURCE="manual"
elif [[ "${{ github.event_name }}" == "release" && "${{ github.event.release.tag_name }}" != "" ]]; then
VERSION="${{ github.event.release.tag_name }}"
VERSION_SOURCE="release"
elif [[ "${GITHUB_REF}" == refs/tags/* ]]; then
VERSION=${GITHUB_REF#refs/tags/}
VERSION_SOURCE="git_tag"
else
BUILD_NUMBER=${{ github.run_number }}
VERSION="dev-${BUILD_NUMBER}"
VERSION_SOURCE="dev_build"
fi
# Clean version string (replace invalid characters)
VERSION=$(echo "$VERSION" | sed 's/[^a-zA-Z0-9._-]/-/g')
# Set outputs
echo "version=$VERSION" >> $GITHUB_OUTPUT
echo "version_source=$VERSION_SOURCE" >> $GITHUB_OUTPUT
echo "branch_name=${BRANCH_NAME:-}" >> $GITHUB_OUTPUT
echo "build_number=${BUILD_NUMBER:-}" >> $GITHUB_OUTPUT
echo "=== Version Information ==="
echo "Version: $VERSION"
echo "Source: $VERSION_SOURCE"
echo "Branch: ${BRANCH_NAME:-N/A}"
echo "Build Number: ${BUILD_NUMBER:-N/A}"
echo "Commit SHA: ${GITHUB_SHA::8}"
echo "=========================="
- name: Check files and create combined Dockerfile
run: |
echo "--- Checking available files ---"
pwd
ls -la
echo "--- Checking if requirements.txt exists ---"
if [ -f requirements.txt ]; then
echo "requirements.txt found:"
cat requirements.txt
else
echo "requirements.txt NOT found!"
echo "Available .txt files:"
find . -name "*.txt" -type f
fi
echo "--- Creating combined Dockerfile ---"
cp Dockerfile Dockerfile.final
# Ensure port 8080 is exposed in the final Dockerfile
if ! grep -q "^EXPOSE 8080" Dockerfile.final; then
echo "\n# Ensure required port is exposed" >> Dockerfile.final
echo "EXPOSE 8080" >> Dockerfile.final
fi
echo "Combined Dockerfile created successfully"
- name: Build Docker image
run: |
IMAGE_ID=${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
VERSION="${{ steps.version.outputs.version }}"
echo "Building Docker image..."
echo "Image ID: $IMAGE_ID"
echo "Version: $VERSION"
# Build the Docker image with version label
docker build \
-f Dockerfile.final \
--label "org.opencontainers.image.version=$VERSION" \
--label "org.opencontainers.image.revision=${{ github.sha }}" \
--label "org.opencontainers.image.created=$(date -u +'%Y-%m-%dT%H:%M:%SZ')" \
--label "org.opencontainers.image.source=${{ github.server_url }}/${{ github.repository }}" \
--label "org.opencontainers.image.exposedPorts=8080" \
--build-arg APP_VERSION="$VERSION" \
-t $IMAGE_ID:$VERSION \
.
# Determine publish tags
if [[ "${{ github.event_name }}" == "release" ]]; then
# Release: publish version and latest
docker tag $IMAGE_ID:$VERSION $IMAGE_ID:latest
echo "Release build: will push tags [$VERSION, latest]"
else
# Non-release: publish development
docker tag $IMAGE_ID:$VERSION $IMAGE_ID:development
echo "Non-release build: will push tag [development]"
fi
- name: Push Docker image
if: github.event_name != 'pull_request'
run: |
IMAGE_ID=${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
VERSION="${{ steps.version.outputs.version }}"
echo "Pushing Docker image..."
echo "Image ID: $IMAGE_ID"
echo "Version: $VERSION"
if [[ "${{ github.event_name }}" == "release" ]]; then
# Push version and latest
docker push $IMAGE_ID:$VERSION
docker push $IMAGE_ID:latest
else
# Push only development
docker push $IMAGE_ID:development
fi
- name: Generate build summary
run: |
echo "=== Build Summary ==="
echo "Repository: ${{ github.repository }}"
echo "Event: ${{ github.event_name }}"
echo "Version: ${{ steps.version.outputs.version }}"
echo "Version Source: ${{ steps.version.outputs.version_source }}"
echo "Branch: ${{ steps.version.outputs.branch_name }}"
echo "Build Number: ${{ steps.version.outputs.build_number }}"
echo "Commit: ${{ github.sha }}"
echo "Image: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.version }}"
echo "===================="
- name: Comment on PR
if: github.event_name == 'pull_request'
uses: actions/github-script@v7
with:
script: |
const { data: comments } = await github.rest.issues.listComments({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
});
const botComment = comments.find(comment => comment.user.type === 'Bot' && comment.body.includes('Docker build completed'));
const commentBody = `## 🐳 Docker Build Completed
**Build Information:**
- **Version:** \`${{ steps.version.outputs.version }}\`
- **Source:** ${{ steps.version.outputs.version_source }}
- **Branch:** ${{ steps.version.outputs.branch_name }}
- **Build Number:** ${{ steps.version.outputs.build_number }}
- **Commit:** \`${{ github.sha }}\`
**Image:** \`${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.version }}\`
> This is a preview build. The image will be pushed when merged to main.
---
*This comment was automatically generated by the Docker build workflow.*`;
if (botComment) {
await github.rest.issues.updateComment({
comment_id: botComment.id,
owner: context.repo.owner,
repo: context.repo.repo,
body: commentBody,
});
} else {
await github.rest.issues.createComment({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
body: commentBody,
});
}