Skip to content

Merge pull request #21 from project-aethermesh/fix/use-the-right-toke… #76

Merge pull request #21 from project-aethermesh/fix/use-the-right-toke…

Merge pull request #21 from project-aethermesh/fix/use-the-right-toke… #76

name: Build and Push Docker Images to GHCR
on:
workflow_dispatch:
inputs:
tag:
description: "Comma-separated list of image tags for manual builds (e.g., 'preprod' or 'latest,v2,v2.1,v2.1.2'). If not set, the branch name is used for non-main branches."
required: false
type: string
push:
branches:
- main
paths:
- "**.go"
- "**/Dockerfile"
- ".github/workflows/build-and-push-images.yaml"
pull_request:
types: [opened, synchronize]
jobs:
setup:
name: Setup workflow
runs-on: ubuntu-latest
outputs:
short_sha: ${{ steps.set_outputs.outputs.short_sha }}
steps:
- name: Checkout
id: checkout
uses: actions/checkout@v6
- name: Set outputs
id: set_outputs
shell: bash
run: |
echo "short_sha=$(git rev-parse --short HEAD)" >> $GITHUB_OUTPUT
test:
name: Run Go tests
runs-on: ubuntu-latest
steps:
- name: Checkout code
id: checkout
uses: actions/checkout@v6
- name: Set up Go
id: setup_go
uses: actions/setup-go@v6
with:
go-version: "1.25"
- name: Run tests
id: run_tests
run: |
go test ./...
check_version:
name: Check VERSION file
runs-on: ubuntu-latest
steps:
- name: Checkout PR branch
if: github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name == github.repository
uses: actions/checkout@v6
with:
ref: ${{ github.event.pull_request.head.ref }}
- name: Checkout main branch
if: github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name == github.repository
uses: actions/checkout@v6
with:
ref: main
path: main-branch
- name: Check VERSION file exists
if: github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name == github.repository
run: |
if [ ! -f "VERSION" ]; then
echo "VERSION file not found in repository root"
echo "Please create a VERSION file with a semantic version (e.g., v1.0.0)"
exit 1
fi
echo "VERSION file exists"
- name: Check VERSION file updated and greater
id: check_version_file_updated_and_greater
if: github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name == github.repository
run: |
if [ -f "main-branch/VERSION" ]; then
PR_VERSION=$(cat VERSION | xargs)
MAIN_VERSION=$(cat main-branch/VERSION | xargs)
# Check if versions are the same
if [ "$PR_VERSION" == "$MAIN_VERSION" ]; then
echo "VERSION file has not been updated"
echo "Current VERSION: $PR_VERSION"
echo "Main branch VERSION: $MAIN_VERSION"
echo "Please update the VERSION file with a new semantic version"
exit 1
fi
echo "PR_VERSION=$PR_VERSION" >> "$GITHUB_OUTPUT"
echo "MAIN_VERSION=$MAIN_VERSION" >> "$GITHUB_OUTPUT"
else
echo "VERSION file is new (not present in main branch)"
fi
- name: Compare PR and main VERSION using shared action
if: github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name == github.repository && steps.check_version_file_updated_and_greater.outcome == 'success' && steps.check_version_file_updated_and_greater.outputs.PR_VERSION != ''
id: compare_pr_main_version
uses: ./.github/actions/compare_versions
with:
v1: ${{ steps.check_version_file_updated_and_greater.outputs.PR_VERSION }}
v2: ${{ steps.check_version_file_updated_and_greater.outputs.MAIN_VERSION }}
- name: Enforce PR VERSION is greater than main VERSION
if: github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name == github.repository && steps.compare_pr_main_version.outputs.result != ''
run: |
PR_VERSION="${{ steps.check_version_file_updated_and_greater.outputs.PR_VERSION }}"
MAIN_VERSION="${{ steps.check_version_file_updated_and_greater.outputs.MAIN_VERSION }}"
RESULT="${{ steps.compare_pr_main_version.outputs.result }}"
if [ "$RESULT" = "eq" ]; then
echo "VERSION is the same as main branch (after removing metadata)"
echo "PR VERSION: $PR_VERSION"
echo "Main branch VERSION: $MAIN_VERSION"
echo "Please update the VERSION file with a greater semantic version"
exit 1
elif [ "$RESULT" = "lt" ]; then
echo "VERSION is less than main branch version"
echo "PR VERSION: $PR_VERSION"
echo "Main branch VERSION: $MAIN_VERSION"
echo "Please update the VERSION file with a greater semantic version"
exit 1
fi
echo "VERSION file has been updated and is greater"
echo "Main branch: $MAIN_VERSION"
echo "PR branch: $PR_VERSION"
- name: Validate VERSION format
if: github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name == github.repository
run: |
VERSION=$(cat VERSION | xargs)
# Check that version starts with 'v'
if [[ ! "$VERSION" == v* ]]; then
echo "Version must start with 'v' prefix"
echo "Current version: $VERSION"
echo "Expected format: v1.0.0 (semantic versioning with 'v' prefix)"
exit 1
fi
# Remove 'v' prefix for validation
VERSION_CLEAN=${VERSION#v}
# Validate semantic versioning format (major.minor.patch)
if [[ ! $VERSION_CLEAN =~ ^[0-9]+\.[0-9]+\.[0-9]+(-[a-zA-Z0-9.-]+)?(\+[a-zA-Z0-9.-]+)?$ ]]; then
echo "Invalid version format: $VERSION"
echo "Expected format: v1.0.0 (semantic versioning with 'v' prefix)"
exit 1
fi
echo "Valid version: $VERSION"
- name: Skip check for non-PR events
if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name != github.repository
run: |
echo "Skipping VERSION check (not a PR or PR is from a fork)"
parse_tags:
name: Parse tags
runs-on: ubuntu-latest
outputs:
tags: ${{ steps.parse_tags.outputs.tags }}
has_custom_tags: ${{ steps.parse_tags.outputs.has_custom_tags }}
steps:
- name: Debug - Show received tags
run: |
echo "Event name: ${{ github.event_name }}"
echo "Received tag input: '${{ github.event.inputs.tag }}'"
if [ -n "${{ github.event.inputs.tag }}" ]; then
echo "Tags breakdown:"
TAGS="${{ github.event.inputs.tag }}"
IFS=',' read -ra TAG_ARRAY <<< "$TAGS"
for tag in "${TAG_ARRAY[@]}"; do
echo " - $tag"
done
fi
- name: Parse tags
id: parse_tags
shell: bash
run: |
if [ "${{ github.event_name }}" == "workflow_dispatch" ] && [ -n "${{ github.event.inputs.tag }}" ]; then
echo "Parsing tags from input: '${{ github.event.inputs.tag }}'"
# Parse comma-separated tags and output as multiline string for docker/metadata-action
IFS=',' read -ra TAGS <<< "${{ github.event.inputs.tag }}"
TAGS_OUTPUT=""
for tag in "${TAGS[@]}"; do
tag=$(echo "$tag" | xargs) # trim whitespace
if [ -n "$tag" ]; then
TAGS_OUTPUT="${TAGS_OUTPUT}type=raw,value=${tag}"$'\n'
echo "Added tag: ${tag}"
fi
done
echo "tags<<EOF" >> $GITHUB_OUTPUT
echo "$TAGS_OUTPUT" >> $GITHUB_OUTPUT
echo "EOF" >> $GITHUB_OUTPUT
echo "has_custom_tags=true" >> $GITHUB_OUTPUT
echo "Parsed tags successfully"
else
echo "has_custom_tags=false" >> $GITHUB_OUTPUT
echo "No custom tags provided (event: ${{ github.event_name }}, has tag input: $([ -n '${{ github.event.inputs.tag }}' ] && echo 'yes' || echo 'no'))"
fi
health-checker:
name: Build health-checker image
runs-on: ubuntu-latest
# Run for all configured events, but skip pull requests from forks
if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository
environment: ${{ github.ref_name == 'main' && 'prod' || 'dev' }}
needs:
- setup
- test
- check_version
- parse_tags
steps:
- name: Checkout code
id: checkout
uses: actions/checkout@v6
- name: Set up Go
id: setup_go
uses: actions/setup-go@v6
with:
go-version: "1.25"
- name: Log in to GitHub Container Registry
id: login_ghcr
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.repository_owner }}
password: ${{ secrets.AETHERLAY_GITHUB_TOKEN }}
- name: Debug - Show tags for health-checker
run: |
echo "Tags from parse_tags job:"
echo "${{ needs.parse_tags.outputs.tags }}"
echo ""
echo "Has custom tags: ${{ needs.parse_tags.outputs.has_custom_tags }}"
echo "Event name: ${{ github.event_name }}"
echo "Ref name: ${{ github.ref_name }}"
echo "Default branch: ${{ github.event.repository.default_branch }}"
- name: Docker meta for health-checker
id: meta_hc
uses: docker/metadata-action@v5
with:
images: ghcr.io/project-aethermesh/aetherlay/aetherlay-hc
tags: |
type=raw,value=latest,enable=${{ github.ref_name == github.event.repository.default_branch && github.event_name != 'pull_request' && needs.parse_tags.outputs.has_custom_tags != 'true' }}
type=sha,format=short,enable=${{ github.ref_name == github.event.repository.default_branch && github.event_name != 'pull_request' }}
type=raw,value=pr-${{ github.event.pull_request.number }},enable=${{ github.event_name == 'pull_request' }}
${{ needs.parse_tags.outputs.tags }}
type=ref,event=branch,enable=${{ github.event_name == 'workflow_dispatch' && needs.parse_tags.outputs.has_custom_tags != 'true' && github.ref_name != github.event.repository.default_branch }}
labels: |
org.opencontainers.image.vendor=Project Aethermesh
org.opencontainers.image.licenses=AGPL-3.0
- name: Debug - Show final tags for health-checker
run: |
echo "Final tags that will be applied:"
echo "${{ steps.meta_hc.outputs.tags }}"
- name: Build and push health-checker image
id: container_image_hc
uses: docker/build-push-action@v6
with:
context: .
file: ./services/health-checker/Dockerfile
push: true
tags: ${{ steps.meta_hc.outputs.tags }}
labels: ${{ steps.meta_hc.outputs.labels }}
load-balancer:
name: Build load-balancer image
runs-on: ubuntu-latest
# Run for all configured events, but skip pull requests from forks
if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository
environment: ${{ github.ref_name == 'main' && 'prod' || 'dev' }}
needs:
- setup
- test
- check_version
- parse_tags
steps:
- name: Checkout code
id: checkout_lb
uses: actions/checkout@v6
- name: Set up Go
id: setup_go
uses: actions/setup-go@v6
with:
go-version: "1.25"
- name: Log in to GitHub Container Registry
id: login_ghcr_lb
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.repository_owner }}
password: ${{ secrets.AETHERLAY_GITHUB_TOKEN }}
- name: Debug - Show tags for load-balancer
run: |
echo "Tags from parse_tags job:"
echo "${{ needs.parse_tags.outputs.tags }}"
echo ""
echo "Has custom tags: ${{ needs.parse_tags.outputs.has_custom_tags }}"
echo "Event name: ${{ github.event_name }}"
echo "Ref name: ${{ github.ref_name }}"
echo "Default branch: ${{ github.event.repository.default_branch }}"
- name: Docker meta for load-balancer
id: meta_lb
uses: docker/metadata-action@v5
with:
images: ghcr.io/project-aethermesh/aetherlay/aetherlay-lb
tags: |
type=raw,value=latest,enable=${{ github.ref_name == github.event.repository.default_branch && github.event_name != 'pull_request' && needs.parse_tags.outputs.has_custom_tags != 'true' }}
type=sha,format=short,enable=${{ github.ref_name == github.event.repository.default_branch && github.event_name != 'pull_request' }}
type=raw,value=pr-${{ github.event.pull_request.number }},enable=${{ github.event_name == 'pull_request' }}
${{ needs.parse_tags.outputs.tags }}
type=ref,event=branch,enable=${{ github.event_name == 'workflow_dispatch' && needs.parse_tags.outputs.has_custom_tags != 'true' && github.ref_name != github.event.repository.default_branch }}
labels: |
org.opencontainers.image.vendor=Project Aethermesh
org.opencontainers.image.licenses=AGPL-3.0
- name: Debug - Show final tags for load-balancer
run: |
echo "Final tags that will be applied:"
echo "${{ steps.meta_lb.outputs.tags }}"
- name: Build and push load-balancer image
id: container_image_lb
uses: docker/build-push-action@v6
with:
context: .
file: ./services/load-balancer/Dockerfile
push: true
tags: ${{ steps.meta_lb.outputs.tags }}
labels: ${{ steps.meta_lb.outputs.labels }}