mirror of
https://github.com/DRYTRIX/TimeTracker.git
synced 2026-04-29 00:40:06 -05:00
223 lines
8.1 KiB
YAML
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,
|
|
});
|
|
}
|