- Removed complex remote URL configuration logic for authentication. - Updated comments to clarify that the remote should already be configured with the token before pushing to the main branch.
269 lines
9.9 KiB
YAML
269 lines
9.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
|
||
token: ${{ secrets.FORGEBOT_ACCESS_TOKEN }}
|
||
|
||
- 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
|
||
# Handle COMMITS separately due to multi-line content that can break sed
|
||
# First, replace all single-line placeholders
|
||
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" \
|
||
"$TEMPLATE_FILE" > /tmp/release_message_temp.txt
|
||
|
||
# Replace COMMITS placeholder - use a while loop to handle multi-line safely
|
||
if [[ -n "$COMMITS" ]]; then
|
||
# Write COMMITS to a temp file and use it for replacement
|
||
echo "$COMMITS" > /tmp/commits.txt
|
||
# Use a simple approach: read template line by line and replace
|
||
while IFS= read -r line; do
|
||
if [[ "$line" == *"{{COMMITS}}"* ]]; then
|
||
cat /tmp/commits.txt
|
||
else
|
||
echo "$line"
|
||
fi
|
||
done < /tmp/release_message_temp.txt > /tmp/release_message.txt
|
||
else
|
||
# If no commits, just remove the placeholder
|
||
sed 's|{{COMMITS}}||g' /tmp/release_message_temp.txt > /tmp/release_message.txt
|
||
fi
|
||
|
||
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 "forgebot"
|
||
git config user.email "forgebot@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 (remote should already be configured with token)
|
||
git push origin main || {
|
||
echo "⚠️ Push failed (check token permissions)"
|
||
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
|
||
|