Skip to content

Merge pull request #2 from objectrocket/build-push-operator #2

Merge pull request #2 from objectrocket/build-push-operator

Merge pull request #2 from objectrocket/build-push-operator #2

name: Build and Publish Operator
on:
push:
branches:
- main
paths:
- 'pkg/**'
- 'cmd/**'
- 'config/**'
- 'deploy/**'
- 'build/**'
- 'go.mod'
- 'go.sum'
- 'Makefile'
- '.github/workflows/build-operator.yml'
release:
types: [published]
workflow_dispatch:
inputs:
tag:
description: 'Tag to build (e.g., v1.21.2-objectrocket)'
required: false
type: string
env:
REGISTRY: ghcr.io
IMAGE_NAME: objectrocket/percona-server-mongodb-operator
GO_VERSION: '1.25'
jobs:
test:
name: Run Tests
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Set up Go
uses: actions/setup-go@v5
with:
go-version: ${{ env.GO_VERSION }}
cache: true
- name: Run unit tests
run: make test
- name: Upload coverage report
uses: codecov/codecov-action@v4
if: always()
with:
files: ./cover.out
flags: unittests
name: operator-coverage
continue-on-error: true
build-and-push:
name: Build and Push Operator Image
runs-on: ubuntu-latest
needs: test
permissions:
contents: read
packages: write
id-token: write
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Log in to GitHub Container Registry
uses: docker/login-action@v3
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Extract version and metadata
id: meta
run: |
# Determine version based on trigger type
if [ "${{ github.event_name }}" = "release" ]; then
VERSION="${{ github.event.release.tag_name }}"
VERSION="${VERSION#v}" # Remove 'v' prefix if present
elif [ "${{ github.event_name }}" = "workflow_dispatch" ] && [ -n "${{ inputs.tag }}" ]; then
VERSION="${{ inputs.tag }}"
VERSION="${VERSION#v}"
else
# For main branch, use version from pkg/version/version.txt or git describe
if [ -f pkg/version/version.txt ]; then
VERSION=$(cat pkg/version/version.txt)
else
VERSION=$(git describe --tags --always --dirty)
fi
VERSION="${VERSION}-objectrocket"
fi
# Extract major.minor version
MAJOR_MINOR=$(echo "$VERSION" | grep -oE '^[0-9]+\.[0-9]+' || echo "")
# Get git metadata
GIT_COMMIT=$(git rev-parse HEAD)
GIT_BRANCH=$(git rev-parse --abbrev-ref HEAD)
BUILD_TIME=$(date -u +"%Y-%m-%dT%H:%M:%SZ")
echo "version=$VERSION" >> $GITHUB_OUTPUT
echo "major_minor=$MAJOR_MINOR" >> $GITHUB_OUTPUT
echo "git_commit=$GIT_COMMIT" >> $GITHUB_OUTPUT
echo "git_branch=$GIT_BRANCH" >> $GITHUB_OUTPUT
echo "build_time=$BUILD_TIME" >> $GITHUB_OUTPUT
# Construct image tags
TAGS="${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${VERSION}"
if [ -n "$MAJOR_MINOR" ]; then
TAGS="${TAGS},${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${MAJOR_MINOR}"
fi
if [ "${{ github.event_name }}" = "push" ] && [ "${{ github.ref }}" = "refs/heads/main" ]; then
TAGS="${TAGS},${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:latest"
fi
echo "tags=$TAGS" >> $GITHUB_OUTPUT
- name: Extract Docker metadata
id: docker_meta
uses: docker/metadata-action@v5
with:
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
tags: |
type=raw,value=${{ steps.meta.outputs.version }}
type=raw,value=${{ steps.meta.outputs.major_minor }},enable=${{ steps.meta.outputs.major_minor != '' }}
type=raw,value=latest,enable=${{ github.event_name == 'push' && github.ref == 'refs/heads/main' }}
labels: |
org.opencontainers.image.title=Percona Server MongoDB Operator
org.opencontainers.image.description=Kubernetes operator for managing Percona Server for MongoDB clusters
org.opencontainers.image.vendor=ObjectRocket
org.opencontainers.image.version=${{ steps.meta.outputs.version }}
org.opencontainers.image.revision=${{ steps.meta.outputs.git_commit }}
org.opencontainers.image.source=${{ github.repositoryUrl }}
org.opencontainers.image.created=${{ steps.meta.outputs.build_time }}
- name: Build and push operator image
uses: docker/build-push-action@v6
with:
context: .
file: ./build/Dockerfile
platforms: linux/amd64,linux/arm64
push: ${{ github.event_name != 'pull_request' }}
tags: ${{ steps.docker_meta.outputs.tags }}
labels: ${{ steps.docker_meta.outputs.labels }}
build-args: |
GIT_COMMIT=${{ steps.meta.outputs.git_commit }}
GIT_BRANCH=${{ steps.meta.outputs.git_branch }}
BUILD_TIME=${{ steps.meta.outputs.build_time }}
cache-from: type=gha
cache-to: type=gha,mode=max
- name: Generate image digest
id: digest
if: github.event_name != 'pull_request'
run: |
DIGEST=$(docker buildx imagetools inspect ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.meta.outputs.version }} --format '{{.Manifest.Digest}}')
echo "digest=$DIGEST" >> $GITHUB_OUTPUT
echo "Image digest: $DIGEST"
build-artifacts:
name: Build and Package Artifacts
runs-on: ubuntu-latest
needs: test
permissions:
contents: write
packages: write
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Set up Go
uses: actions/setup-go@v5
with:
go-version: ${{ env.GO_VERSION }}
cache: true
- name: Generate CRDs and manifests
run: |
make generate
make manifests
- name: Create artifact directory
run: |
mkdir -p artifacts
cp deploy/crd.yaml artifacts/
cp deploy/rbac.yaml artifacts/
cp deploy/cw-rbac.yaml artifacts/
cp deploy/operator.yaml artifacts/
cp deploy/cw-operator.yaml artifacts/
cp deploy/bundle.yaml artifacts/
cp deploy/cw-bundle.yaml artifacts/
- name: Upload CRDs and RBAC artifacts
uses: actions/upload-artifact@v4
with:
name: operator-manifests
path: artifacts/
retention-days: 30
- name: Create release artifacts (on release)
if: github.event_name == 'release'
run: |
tar -czf operator-manifests-${{ github.event.release.tag_name }}.tar.gz -C artifacts .
- name: Upload release artifacts
if: github.event_name == 'release'
uses: actions/upload-release-asset@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
upload_url: ${{ github.event.release.upload_url }}
asset_path: ./operator-manifests-${{ github.event.release.tag_name }}.tar.gz
asset_name: operator-manifests-${{ github.event.release.tag_name }}.tar.gz
asset_content_type: application/gzip
continue-on-error: true
summary:
name: Build Summary
runs-on: ubuntu-latest
needs: [test, build-and-push, build-artifacts]
if: always()
steps:
- name: Generate summary
run: |
echo "## Operator Build Summary" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "**Workflow:** ${{ github.workflow }}" >> $GITHUB_STEP_SUMMARY
echo "**Trigger:** ${{ github.event_name }}" >> $GITHUB_STEP_SUMMARY
echo "**Branch:** ${{ github.ref_name }}" >> $GITHUB_STEP_SUMMARY
echo "**Commit:** ${{ github.sha }}" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "### Job Status" >> $GITHUB_STEP_SUMMARY
echo "- Tests: ${{ needs.test.result }}" >> $GITHUB_STEP_SUMMARY
echo "- Build and Push: ${{ needs.build-and-push.result }}" >> $GITHUB_STEP_SUMMARY
echo "- Build Artifacts: ${{ needs.build-artifacts.result }}" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
if [ "${{ needs.build-and-push.result }}" = "success" ]; then
echo "### Published Images" >> $GITHUB_STEP_SUMMARY
echo "- \`${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}\`" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "### Next Steps" >> $GITHUB_STEP_SUMMARY
echo "The manifest update workflow will automatically update deployment manifests in liberty-infrastructure." >> $GITHUB_STEP_SUMMARY
fi