250 lines
9 KiB
YAML
250 lines
9 KiB
YAML
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 --build-arg VERSION=test --build-arg BUILD_DATE=$(date -u +"%Y-%m-%dT%H:%M:%SZ") -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
|
||
|
||
- name: Job Summary
|
||
if: success()
|
||
run: |
|
||
SUMMARY_FILE="${FORGEJO_STEP_SUMMARY}"
|
||
cat >> "$SUMMARY_FILE" << 'EOF'
|
||
## ✅ Build and Validation Complete
|
||
|
||
- ✅ Docker image built successfully
|
||
- ✅ Image validated (container started and HTTP check passed)
|
||
|
||
The image is ready for deployment.
|
||
EOF
|
||
|
||
publish:
|
||
name: Publish to Registry
|
||
runs-on: ubuntu
|
||
needs: build-and-validate
|
||
if: github.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"
|
||
echo "Current VERSION file: $(cat VERSION 2>/dev/null || echo 'not found')"
|
||
|
||
- name: Build Docker Image
|
||
run: |
|
||
VERSION="${{ steps.version.outputs.version }}"
|
||
BUILD_DATE=$(date -u +"%Y-%m-%dT%H:%M:%SZ")
|
||
IMAGE_NAME="git.jusemon.com/jusemon/threejs-test:$VERSION"
|
||
docker build --build-arg VERSION="$VERSION" --build-arg BUILD_DATE="$BUILD_DATE" -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: Generate Release Notes
|
||
id: release_notes
|
||
run: |
|
||
VERSION="${{ steps.version.outputs.version }}"
|
||
TAG="${{ steps.version.outputs.tag }}"
|
||
IMAGE_NAME="git.jusemon.com/jusemon/threejs-test:$VERSION"
|
||
COMMIT_HASH=$(git rev-parse HEAD)
|
||
COMMIT_SHORT=$(git rev-parse --short HEAD)
|
||
BUILD_DATE=$(date -u +"%Y-%m-%d %H:%M:%S UTC")
|
||
|
||
# Get commits since last tag
|
||
LATEST_TAG=$(git describe --tags --match 'v*.*.*' --abbrev=0 2>/dev/null || echo "")
|
||
if [[ -n "$LATEST_TAG" ]]; then
|
||
COMMITS=$(git log ${LATEST_TAG}..HEAD --pretty=format:"- %s (%h)" --no-merges)
|
||
else
|
||
COMMITS=$(git log --pretty=format:"- %s (%h)" --no-merges -10)
|
||
fi
|
||
|
||
# Get author of the commit
|
||
COMMIT_AUTHOR=$(git log -1 --pretty=format:"%an <%ae>")
|
||
|
||
# Read template and replace placeholders
|
||
TEMPLATE_FILE=".forgejo/release-template.md"
|
||
if [[ ! -f "$TEMPLATE_FILE" ]]; then
|
||
echo "Error: Template file not found: $TEMPLATE_FILE"
|
||
exit 1
|
||
fi
|
||
|
||
# Replace placeholders in template
|
||
sed -e "s|{{VERSION}}|$VERSION|g" \
|
||
-e "s|{{IMAGE_NAME}}|$IMAGE_NAME|g" \
|
||
-e "s|{{COMMIT_HASH}}|$COMMIT_HASH|g" \
|
||
-e "s|{{COMMIT_SHORT}}|$COMMIT_SHORT|g" \
|
||
-e "s|{{BUILD_DATE}}|$BUILD_DATE|g" \
|
||
-e "s|{{COMMIT_AUTHOR}}|$COMMIT_AUTHOR|g" \
|
||
-e "s|{{COMMITS}}|$COMMITS|g" \
|
||
"$TEMPLATE_FILE" > /tmp/release_message.txt
|
||
|
||
echo "Release notes generated from template"
|
||
|
||
- 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"
|
||
echo "TAG_CREATED=false" >> $GITHUB_ENV
|
||
else
|
||
git tag -a "$TAG" -F /tmp/release_message.txt
|
||
git push origin "$TAG"
|
||
echo "Created tag $TAG with detailed release notes"
|
||
echo "TAG_CREATED=true" >> $GITHUB_ENV
|
||
fi
|
||
|
||
- name: Update Version Files
|
||
run: |
|
||
VERSION="${{ steps.version.outputs.version }}"
|
||
TAG="${{ steps.version.outputs.tag }}"
|
||
|
||
echo "📝 Updating version files to: $VERSION"
|
||
|
||
# Configure git
|
||
git config user.name "forgejo-actions"
|
||
git config user.email "forgejo-actions@forgejo.io"
|
||
|
||
# Fetch latest changes to avoid conflicts
|
||
git fetch origin main || echo "Fetch completed or already up to date"
|
||
git checkout main || echo "Already on main"
|
||
|
||
# Update VERSION file
|
||
echo "$VERSION" > VERSION
|
||
|
||
# Update portainer.yml with new version
|
||
sed -i "s|\(image: git.jusemon.com/jusemon/threejs-test:\)[0-9.]*|\1$VERSION|" portainer.yml
|
||
|
||
# Verify the updates
|
||
if grep -q "^$VERSION$" VERSION && grep -q "image: git.jusemon.com/jusemon/threejs-test:$VERSION" portainer.yml; then
|
||
echo "✅ Successfully updated VERSION and portainer.yml to $VERSION"
|
||
else
|
||
echo "❌ Failed to update version files"
|
||
exit 1
|
||
fi
|
||
|
||
# Check if there are changes to commit
|
||
if git diff --quiet VERSION portainer.yml; then
|
||
echo "ℹ️ No changes to commit (files already up to date)"
|
||
else
|
||
# Stage and commit with [skip ci] to prevent infinite loop
|
||
# Note: Forgejo Actions should respect [skip ci] in commit messages
|
||
git add VERSION portainer.yml
|
||
git commit -m "chore: update version to $VERSION [skip ci]" || {
|
||
echo "⚠️ Commit failed (may already be committed)"
|
||
exit 0
|
||
}
|
||
|
||
# Push to main branch
|
||
git push origin main || {
|
||
echo "⚠️ Push failed (may need manual intervention or branch protection)"
|
||
exit 0
|
||
}
|
||
|
||
echo "✅ Successfully committed and pushed version update to $VERSION"
|
||
fi
|
||
|
||
- name: Job Summary
|
||
if: success()
|
||
run: |
|
||
SUMMARY_FILE="${FORGEJO_STEP_SUMMARY:-/dev/stdout}"
|
||
VERSION="${{ steps.version.outputs.version }}"
|
||
TAG="${{ steps.version.outputs.tag }}"
|
||
IMAGE_NAME="git.jusemon.com/jusemon/threejs-test:$VERSION"
|
||
TAG_STATUS="${TAG_CREATED:-false}"
|
||
|
||
cat >> "$SUMMARY_FILE" << EOF
|
||
## 🚀 Release Published
|
||
|
||
**Version:** \`$VERSION\`
|
||
**Docker Image:** \`$IMAGE_NAME\`
|
||
**Git Tag:** \`$TAG\`
|
||
|
||
### Published Images
|
||
- ✅ \`$IMAGE_NAME\`
|
||
- ✅ \`git.jusemon.com/jusemon/threejs-test:latest\`
|
||
|
||
### Git Tag
|
||
EOF
|
||
|
||
if [[ "$TAG_STATUS" == "true" ]]; then
|
||
echo "- ✅ Created and pushed \`$TAG\` with release notes" >> "$SUMMARY_FILE"
|
||
else
|
||
echo "- ⚠️ Tag \`$TAG\` already exists, skipped creation" >> "$SUMMARY_FILE"
|
||
fi
|
||
|
||
cat >> "$SUMMARY_FILE" << EOF
|
||
|
||
### Version Files
|
||
- ✅ VERSION file updated to \`$VERSION\`
|
||
- ✅ portainer.yml updated to \`$VERSION\`
|
||
|
||
### Pull Command
|
||
\`\`\`bash
|
||
docker pull git.jusemon.com/jusemon/threejs-test:latest
|
||
\`\`\`
|
||
EOF
|
||
|