Docker Build and Release #244
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Docker Build and Release | |
| on: | |
| schedule: | |
| - cron: '45 21 * * *' | |
| push: | |
| branches: [ "main" ] | |
| pull_request: | |
| branches: [ "main" ] | |
| env: | |
| REGISTRY: ghcr.io | |
| IMAGE_NAME: ${{ github.repository }} | |
| NEW_TAG: v0.0.0 | |
| jobs: | |
| build-and-release: | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: write | |
| packages: write | |
| id-token: write | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| with: | |
| fetch-depth: 0 | |
| token: ${{ secrets.CR_PAT }} | |
| # Check if this is a scheduled build that was just pushed | |
| - name: Check for scheduled build push | |
| id: check_scheduled | |
| run: | | |
| if [[ "${{ github.event_name }}" == "push" ]]; then | |
| # Get the last commit message | |
| LAST_COMMIT=$(git log -1 --pretty=%B) | |
| if [[ "$LAST_COMMIT" == *"Release nightly"* ]]; then | |
| echo "is_scheduled_push=true" >> $GITHUB_OUTPUT | |
| echo "This appears to be a scheduled build that was just pushed, skipping build" | |
| exit 0 | |
| fi | |
| fi | |
| echo "is_scheduled_push=false" >> $GITHUB_OUTPUT | |
| # Version tagging logic | |
| - name: Version tagging | |
| if: github.event_name != 'pull_request' && !startsWith(github.ref, 'refs/tags/') && steps.check_scheduled.outputs.is_scheduled_push != 'true' | |
| run: | | |
| # Get the latest tag or set to v0.0.0 if none exists | |
| LATEST_TAG=$(git describe --tags --abbrev=0 2>/dev/null || echo "v0.0.0") | |
| echo "LATEST_TAG=$LATEST_TAG" >> $GITHUB_ENV | |
| # Find the last semantic version tag | |
| LAST_SEMVER=$(git tag -l "v[0-9]*.[0-9]*.[0-9]*" --sort=-v:refname | head -n 1 || echo "v0.0.0") | |
| echo "LAST_SEMVER=$LAST_SEMVER" >> $GITHUB_ENV | |
| # Extract version components from the last semantic version | |
| MAJOR=$(echo $LAST_SEMVER | sed 's/v\([0-9]*\)\..*/\1/') | |
| MINOR=$(echo $LAST_SEMVER | sed 's/v[0-9]*\.\([0-9]*\)\..*/\1/') | |
| PATCH=$(echo $LAST_SEMVER | sed 's/v[0-9]*\.[0-9]*\.\([0-9]*\).*/\1/') | |
| # Determine version bump | |
| if [[ "${{ github.event.head_commit.message }}" == *"#major"* ]]; then | |
| NEW_MAJOR=$((MAJOR + 1)) | |
| NEW_MINOR=0 | |
| NEW_PATCH=0 | |
| elif [[ "${{ github.event.head_commit.message }}" == *"#minor"* ]]; then | |
| NEW_MAJOR=$MAJOR | |
| NEW_MINOR=$((MINOR + 1)) | |
| NEW_PATCH=0 | |
| else | |
| NEW_MAJOR=$MAJOR | |
| NEW_MINOR=$MINOR | |
| NEW_PATCH=$((PATCH + 1)) | |
| fi | |
| # For scheduled runs, use nightly tag | |
| if [[ "${{ github.event_name }}" == "schedule" ]]; then | |
| NEW_TAG="nightly-$(date +%Y%m%d)" | |
| echo "NIGHTLY=true" >> $GITHUB_ENV | |
| else | |
| # For manual pushes, use semantic versioning | |
| NEW_TAG="v$NEW_MAJOR.$NEW_MINOR.$NEW_PATCH" | |
| echo "NIGHTLY=false" >> $GITHUB_ENV | |
| fi | |
| # Check if tag already exists | |
| if git tag -l | grep -q "^$NEW_TAG$"; then | |
| echo "Tag $NEW_TAG already exists, skipping tag creation" | |
| exit 0 | |
| fi | |
| echo "NEW_TAG=$NEW_TAG" >> $GITHUB_ENV | |
| - name: Create and push tag | |
| if: github.event_name != 'pull_request' && !startsWith(github.ref, 'refs/tags/') && env.NEW_TAG != '' && steps.check_scheduled.outputs.is_scheduled_push != 'true' | |
| run: | | |
| git config --local user.email "github-actions[bot]@users.noreply.github.com" | |
| git config --local user.name "github-actions[bot]" | |
| git tag -a ${{ env.NEW_TAG }} -m "Release ${{ env.NEW_TAG }}" | |
| git push https://${GITHUB_ACTOR}:${GITHUB_TOKEN}@github.com/${GITHUB_REPOSITORY}.git ${{ env.NEW_TAG }} | |
| env: | |
| GITHUB_TOKEN: ${{ secrets.CR_PAT }} | |
| - name: Create GitHub Release | |
| if: env.NIGHTLY != 'true' && steps.check_scheduled.outputs.is_scheduled_push != 'true' | |
| uses: softprops/action-gh-release@v1 | |
| with: | |
| tag_name: ${{ env.NEW_TAG }} | |
| name: Release ${{ env.NEW_TAG }} | |
| generate_release_notes: true | |
| draft: false | |
| prerelease: false | |
| env: | |
| GITHUB_TOKEN: ${{ secrets.CR_PAT }} | |
| # Docker build and push setup | |
| - name: Set up QEMU | |
| if: steps.check_scheduled.outputs.is_scheduled_push != 'true' | |
| uses: docker/setup-qemu-action@v3 | |
| - name: Set up Docker Buildx | |
| if: steps.check_scheduled.outputs.is_scheduled_push != 'true' | |
| uses: docker/setup-buildx-action@f95db51fddba0c2d1ec667646a06c2ce06100226 | |
| - name: Log into registry ${{ env.REGISTRY }} | |
| if: github.event_name != 'pull_request' && steps.check_scheduled.outputs.is_scheduled_push != 'true' | |
| uses: docker/login-action@343f7c4344506bcbf9b4de18042ae17996df046d | |
| with: | |
| registry: ${{ env.REGISTRY }} | |
| username: ${{ github.actor }} | |
| password: ${{ secrets.CR_PAT }} | |
| - name: Extract Docker metadata | |
| if: steps.check_scheduled.outputs.is_scheduled_push != 'true' | |
| id: meta | |
| uses: docker/metadata-action@96383f45573cb7f253c731d3b3ab81c87ef81934 | |
| with: | |
| images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} | |
| tags: | | |
| type=raw,value=latest,enable=${{ env.NIGHTLY != 'true' }} | |
| type=raw,value=${{ env.NEW_TAG }} | |
| type=raw,value=${{ env.NEW_TAG }}-{{sha}} | |
| type=raw,value=nightly,enable=${{ env.NIGHTLY == 'true' }} | |
| - name: Build and push Docker image | |
| if: steps.check_scheduled.outputs.is_scheduled_push != 'true' | |
| id: build-and-push | |
| uses: docker/build-push-action@0565240e2d4ab88bba5387d719585280857ece09 | |
| with: | |
| context: . | |
| push: ${{ github.event_name != 'pull_request' }} | |
| platforms: linux/amd64,linux/arm64 | |
| tags: ${{ steps.meta.outputs.tags }} | |
| labels: ${{ steps.meta.outputs.labels }} | |
| cache-from: type=gha | |
| cache-to: type=gha,mode=max | |
| # Install cosign for image signing | |
| - name: Install cosign | |
| if: github.event_name != 'pull_request' && steps.check_scheduled.outputs.is_scheduled_push != 'true' | |
| uses: sigstore/cosign-installer@59acb6260d9c0ba8f4a2f9d9b48431a222b68e20 | |
| with: | |
| cosign-release: 'v2.2.4' | |
| - name: Sign the published Docker image | |
| if: ${{ github.event_name != 'pull_request' && steps.check_scheduled.outputs.is_scheduled_push != 'true' }} | |
| env: | |
| TAGS: ${{ steps.meta.outputs.tags }} | |
| DIGEST: ${{ steps.build-and-push.outputs.digest }} | |
| run: echo "${TAGS}" | xargs -I {} cosign sign --yes {}@${DIGEST} |