check if adding a new path works #65
This file contains 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: Build and Push Docker Images to GHCR (User-Specified or Auto-Increment Version) | |
on: | |
workflow_dispatch: | |
inputs: | |
version: | |
description: "Specify a custom version (e.g., 1.5). Leave empty for auto-increment." | |
required: false | |
default: "" | |
push: | |
branches: | |
- main | |
paths: | |
- "**/**" # Detect any file changes at top level | |
permissions: | |
contents: read | |
packages: write | |
jobs: | |
build-and-push: | |
runs-on: ubuntu-latest | |
# Make the ephemeral Docker config apply to the entire job | |
env: | |
DOCKER_CONFIG: /tmp/docker-config | |
steps: | |
################################################################## | |
# 1) CHECK OUT CODE | |
################################################################## | |
- name: Checkout Repository | |
uses: actions/checkout@v3 | |
with: | |
fetch-depth: 2 # Ensure we have a previous commit if it exists | |
################################################################## | |
# 2) PREPARE EPHEMERAL DOCKER CONFIG FOLDER | |
################################################################## | |
- name: Prepare Ephemeral Docker Config | |
run: mkdir -p /tmp/docker-config | |
################################################################## | |
# 3) CONVERT REPO OWNER TO LOWERCASE | |
################################################################## | |
- name: Convert Repository Owner to Lowercase | |
run: echo "OWNER=$(echo ${{ github.repository_owner }} | tr '[:upper:]' '[:lower:]')" >> $GITHUB_ENV | |
################################################################## | |
# 4) DETECT CHANGED DIRECTORIES | |
################################################################## | |
- name: Detect Changed Directories | |
id: detect | |
run: | | |
echo "=== Detecting changed top-level directories ===" | |
# If there's a previous commit, find changed directories | |
if git rev-parse HEAD^ >/dev/null 2>&1; then | |
CHANGED_DIRS=$(git diff --name-only HEAD^ HEAD -- | awk -F/ '{print $1}' | sort -u | grep -v '^\.' || true) | |
else | |
# If first commit, consider all top-level directories | |
CHANGED_DIRS=$(ls -d */ | cut -f1 -d'/' | grep -v '^\.' || true) | |
fi | |
echo "Raw changed directories: $CHANGED_DIRS" | |
# Convert to space-separated for looping | |
echo "CHANGED_DIRS=$(echo "$CHANGED_DIRS" | tr '\n' ' ')" >> $GITHUB_ENV | |
################################################################## | |
# 5) LOG IN TO GHCR (SECURELY, WITH EPHEMERAL CONFIG) | |
################################################################## | |
- name: Log in to GitHub Container Registry | |
run: | | |
echo "${{ secrets.GHCR_TOKEN }}" | docker login ghcr.io -u "${{ github.actor }}" --password-stdin | |
echo "Successfully logged in using ephemeral Docker config at $DOCKER_CONFIG" | |
################################################################## | |
# 6) BUILD AND PUSH DOCKER IMAGES | |
################################################################## | |
- name: Build and Push Docker Images | |
run: | | |
# If no directories changed, skip | |
if [ -z "${{ env.CHANGED_DIRS }}" ]; then | |
echo "No top-level directories changed. Skipping build." | |
exit 0 | |
fi | |
echo "Directories to process: ${{ env.CHANGED_DIRS }}" | |
# Check if user provided a custom version | |
USER_SPECIFIED_VERSION="${{ github.event.inputs.version }}" | |
echo "User-specified version: $USER_SPECIFIED_VERSION (empty = auto)" | |
for dir in ${{ env.CHANGED_DIRS }}; do | |
if [ ! -d "$dir" ]; then | |
echo "Skipping '$dir' (not a directory)." | |
continue | |
fi | |
echo "=== Processing directory: $dir ===" | |
# If user specified a version, use it; otherwise auto-detect | |
if [ -n "$USER_SPECIFIED_VERSION" ]; then | |
NEW_VERSION="$USER_SPECIFIED_VERSION" | |
echo "Using user-specified version: $NEW_VERSION" | |
else | |
################################################################## | |
# AUTO-INCREMENT LOGIC | |
################################################################## | |
PACKAGE_URL="https://api.github.com/orgs/pacificcommunity/packages/container/$dir/versions" | |
echo "Fetching GHCR versions from: $PACKAGE_URL" | |
API_RESPONSE=$(curl -s \ | |
-H "Authorization: Bearer ${{ secrets.GHCR_TOKEN }}" \ | |
-H "Accept: application/vnd.github.v3+json" \ | |
"$PACKAGE_URL") | |
echo "GHCR API Response: $API_RESPONSE" | |
# If package not found => start at 1.0 | |
if echo "$API_RESPONSE" | grep -q '"message": "Package not found."'; then | |
NEW_VERSION="1.0" | |
echo "Package '$dir' not found. Starting at version 1.0." | |
else | |
# Check if GHCR returned a valid array | |
IS_ARRAY=$(echo "$API_RESPONSE" | jq -r 'type' 2>/dev/null || true) | |
if [ "$IS_ARRAY" != "array" ]; then | |
NEW_VERSION="1.0" | |
echo "GHCR response not an array. Starting at 1.0." | |
else | |
# Regex allows optional 'v' prefix: ^v?[0-9]+\.[0-9]+$ | |
VERSION_TAGS=$(echo "$API_RESPONSE" | jq -r ' | |
[.[].metadata.container.tags? // [] | .[]] | |
| map(select(test("^v?[0-9]+\\.[0-9]+$") and . != "latest")) | |
| sort | |
| last | |
') | |
if [ -z "$VERSION_TAGS" ] || [ "$VERSION_TAGS" = "null" ]; then | |
NEW_VERSION="1.0" | |
echo "No valid versions found for '$dir'. Starting at 1.0." | |
else | |
# Strip leading 'v' if present, then increment minor | |
CLEAN_VERSION=$(echo "$VERSION_TAGS" | sed 's/^v//') | |
NEW_VERSION=$(awk -F. '{print $1 "." $2+1}' <<< "$CLEAN_VERSION") | |
echo "Latest version: $CLEAN_VERSION => Incremented to: $NEW_VERSION" | |
fi | |
fi | |
fi | |
fi | |
echo "Final version for '$dir': $NEW_VERSION" | |
IMAGE_NAME="ghcr.io/${{ env.OWNER }}/$dir" | |
echo "Docker Image Name: $IMAGE_NAME" | |
echo "=== Building Docker image: $IMAGE_NAME:v$NEW_VERSION ===" | |
docker build -t "$IMAGE_NAME:v$NEW_VERSION" -t "$IMAGE_NAME:latest" "$dir/" | |
docker push "$IMAGE_NAME:v$NEW_VERSION" | |
docker push "$IMAGE_NAME:latest" | |
echo "=== Done with $dir (version $NEW_VERSION) ===" | |
done |