feat: Add GitHub Actions for automated Docker image builds

Add comprehensive CI/CD pipeline for building and publishing Docker images
to GitHub Container Registry (ghcr.io).

Components:
- build-and-push.yaml: Main workflow for building and pushing images
  - Triggers on push to main, tags, PRs, and manual dispatch
  - Multi-tag strategy (latest, semver, sha, branch)
  - Docker buildx with layer caching
  - Automatic GHCR authentication
  - Platform: linux/amd64

- release.yaml: Automated GitHub releases on version tags
  - Auto-generates release notes from commits
  - Creates GitHub release with Docker pull command

- dependabot.yml: Automated dependency updates
  - Weekly updates for GitHub Actions
  - Weekly updates for Docker base images

- PULL_REQUEST_TEMPLATE.md: PR template with testing checklist

Updated README:
- Add build status badge
- Update image pull instructions
- Reference automated builds

Image tagging strategy:
- main branch → :latest, :main, :main-{sha}
- v1.2.3 tag → :v1.2.3, :1.2, :1, :latest
- PR → :pr-{number}

Generated with [Claude Code](https://claude.ai/code)
via [Happy](https://happy.engineering)

Co-Authored-By: Claude <noreply@anthropic.com>
Co-Authored-By: Happy <yesreply@happy.engineering>
This commit is contained in:
2026-02-15 08:34:06 -05:00
parent 667845b9a2
commit 46b2077f99
5 changed files with 186 additions and 3 deletions
+64
View File
@@ -0,0 +1,64 @@
name: Build and Push Docker Image
on:
push:
branches:
- main
tags:
- 'v*'
pull_request:
branches:
- main
workflow_dispatch:
env:
REGISTRY: ghcr.io
IMAGE_NAME: ${{ github.repository }}
jobs:
build-and-push:
runs-on: ubuntu-latest
permissions:
contents: read
packages: write
id-token: write
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Log in to GitHub 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: Extract metadata (tags, labels)
id: meta
uses: docker/metadata-action@v5
with:
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
tags: |
type=ref,event=branch
type=ref,event=pr
type=semver,pattern={{version}}
type=semver,pattern={{major}}.{{minor}}
type=semver,pattern={{major}}
type=sha,prefix={{branch}}-
type=raw,value=latest,enable={{is_default_branch}}
- name: Build and push Docker image
uses: docker/build-push-action@v5
with:
context: .
push: ${{ github.event_name != 'pull_request' }}
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
cache-from: type=gha
cache-to: type=gha,mode=max
platforms: linux/amd64
+51
View File
@@ -0,0 +1,51 @@
name: Release
on:
push:
tags:
- 'v*'
permissions:
contents: write
packages: write
jobs:
release:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Generate Release Notes
id: notes
run: |
# Get the tag message or generate from commits
TAG_MESSAGE=$(git tag -l --format='%(contents)' ${{ github.ref_name }})
if [ -z "$TAG_MESSAGE" ]; then
# Generate from commit messages since last tag
PREV_TAG=$(git describe --tags --abbrev=0 ${{ github.ref_name }}^ 2>/dev/null || echo "")
if [ -z "$PREV_TAG" ]; then
COMMITS=$(git log --pretty=format:"- %s (%h)" ${{ github.ref_name }})
else
COMMITS=$(git log --pretty=format:"- %s (%h)" ${PREV_TAG}..${{ github.ref_name }})
fi
NOTES="## Changes\n\n${COMMITS}\n\n## Docker Image\n\n\`\`\`bash\ndocker pull ghcr.io/${{ github.repository }}:${{ github.ref_name }}\n\`\`\`"
else
NOTES="${TAG_MESSAGE}\n\n## Docker Image\n\n\`\`\`bash\ndocker pull ghcr.io/${{ github.repository }}:${{ github.ref_name }}\n\`\`\`"
fi
echo "notes<<EOF" >> $GITHUB_OUTPUT
echo -e "$NOTES" >> $GITHUB_OUTPUT
echo "EOF" >> $GITHUB_OUTPUT
- name: Create Release
uses: actions/create-release@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
tag_name: ${{ github.ref_name }}
release_name: Release ${{ github.ref_name }}
body: ${{ steps.notes.outputs.notes }}
draft: false
prerelease: false