From de72274efdf948f0d0988d975b858ba5b4e0bb8e Mon Sep 17 00:00:00 2001 From: Erich Blume Date: Sat, 24 Jan 2026 16:52:44 -0800 Subject: [PATCH] Refactor container build to use generic workflow - Replace per-container build-.yaml with single build-container.yaml - Workflow triggers on *-v* tags, parses container name from tag prefix - Checks containers//Dockerfile exists, skips gracefully if not - Rename container-release to container-tag-and-release for clarity - Update container-list to scan containers/ directory Co-Authored-By: Claude Opus 4.5 --- .forgejo/workflows/build-container.yaml | 76 +++++++++++++++++++ .forgejo/workflows/build-nettest.yaml | 42 ---------- mise-tasks/container-list | 30 +++----- ...iner-release => container-tag-and-release} | 27 ++++--- 4 files changed, 100 insertions(+), 75 deletions(-) create mode 100644 .forgejo/workflows/build-container.yaml delete mode 100644 .forgejo/workflows/build-nettest.yaml rename mise-tasks/{container-release => container-tag-and-release} (66%) diff --git a/.forgejo/workflows/build-container.yaml b/.forgejo/workflows/build-container.yaml new file mode 100644 index 0000000..60771fe --- /dev/null +++ b/.forgejo/workflows/build-container.yaml @@ -0,0 +1,76 @@ +# Generic container build workflow +# Triggers on tags matching: -v +# Builds from containers//Dockerfile if it exists +# +# Examples: +# nettest-v1.0.0 -> builds containers/nettest/ +# devpi-v2.1.0 -> builds containers/devpi/ +# foo-v1.0.0 -> skips if containers/foo/ doesn't exist +name: Build Container + +on: + push: + tags: + - '*-v[0-9]*' + +jobs: + build: + runs-on: ubuntu-latest + steps: + - name: Parse tag + id: parse + run: | + TAG="${GITHUB_REF_NAME}" + echo "Tag: $TAG" + + # Extract container name (everything before -v) + # e.g., "nettest-v1.0.0" -> "nettest", "my-app-v2.0.0" -> "my-app" + CONTAINER="${TAG%-v[0-9]*}" + VERSION="${TAG#"${CONTAINER}"-}" + + echo "container=$CONTAINER" >> "$GITHUB_OUTPUT" + echo "version=$VERSION" >> "$GITHUB_OUTPUT" + echo "Container: $CONTAINER" + echo "Version: $VERSION" + + - name: Checkout + uses: actions/checkout@v4 + + - name: Check if container exists + id: check + run: | + CONTAINER="${{ steps.parse.outputs.container }}" + CONTEXT="containers/$CONTAINER" + + if [ -f "$CONTEXT/Dockerfile" ]; then + echo "Found $CONTEXT/Dockerfile" + echo "exists=true" >> "$GITHUB_OUTPUT" + echo "context=$CONTEXT" >> "$GITHUB_OUTPUT" + else + echo "No Dockerfile found at $CONTEXT/Dockerfile" + echo "exists=false" >> "$GITHUB_OUTPUT" + fi + + - name: Skip if container not found + if: steps.check.outputs.exists != 'true' + run: | + echo "========================================" + echo "Container not found: ${{ steps.parse.outputs.container }}" + echo "========================================" + echo "" + echo "Tag '${{ github.ref_name }}' does not match any container in containers/" + echo "" + echo "Available containers:" + find containers -maxdepth 1 -mindepth 1 -type d -exec basename {} \; 2>/dev/null | sort | while read -r name; do + echo " - $name" + done || echo " (none)" + echo "" + echo "Skipping build." + + - name: Build and push image + if: steps.check.outputs.exists == 'true' + uses: ./.forgejo/actions/build-push-image + with: + context: ${{ steps.check.outputs.context }} + image_name: blumeops/${{ steps.parse.outputs.container }} + version: ${{ steps.parse.outputs.version }} diff --git a/.forgejo/workflows/build-nettest.yaml b/.forgejo/workflows/build-nettest.yaml deleted file mode 100644 index 8597b01..0000000 --- a/.forgejo/workflows/build-nettest.yaml +++ /dev/null @@ -1,42 +0,0 @@ -# Build workflow for nettest container -# Triggered by tags: nettest-v* -# -# This container tests network connectivity to tailnet services. -# Use it to debug CI/CD networking issues. -name: Build nettest - -on: - push: - tags: - - 'nettest-v*' - -jobs: - build: - runs-on: ubuntu-latest - steps: - - name: Checkout - uses: actions/checkout@v4 - - - name: Extract version from tag - id: version - run: | - # Tag is like "nettest-v1.0.0", extract "v1.0.0" - VERSION="${GITHUB_REF_NAME#nettest-}" - echo "version=$VERSION" >> "$GITHUB_OUTPUT" - echo "Building version: $VERSION" - - - name: Build and push image - uses: ./.forgejo/actions/build-push-image - with: - context: containers/nettest - image_name: blumeops/nettest - version: ${{ steps.version.outputs.version }} - - - name: Test connectivity from Docker on indri - run: | - echo "========================================" - echo "Testing connectivity from Docker context" - echo "========================================" - echo "" - # Run the nettest container to verify Docker on indri can reach tailnet services - docker run --rm registry.tail8d86e.ts.net/blumeops/nettest:${{ steps.version.outputs.version }} diff --git a/mise-tasks/container-list b/mise-tasks/container-list index 21a2ad9..3f572ad 100755 --- a/mise-tasks/container-list +++ b/mise-tasks/container-list @@ -4,32 +4,24 @@ set -euo pipefail REGISTRY="registry.tail8d86e.ts.net" -WORKFLOW_DIR=".forgejo/workflows" +CONTAINER_DIR="containers" echo "Container Images" echo "================" echo "" -# Find all build-*.yaml workflows -for workflow in "$WORKFLOW_DIR"/build-*.yaml; do - [[ -f "$workflow" ]] || continue +# Find all container directories with Dockerfiles +for dir in "$CONTAINER_DIR"/*/; do + [[ -d "$dir" ]] || continue + [[ -f "$dir/Dockerfile" ]] || continue - # Extract container name from filename: build-runner.yaml -> runner - filename=$(basename "$workflow") - container="${filename#build-}" - container="${container%.yaml}" - - # Skip if not a container build workflow (check for image_name) - if ! grep -q "image_name:" "$workflow" 2>/dev/null; then - continue - fi - - # Extract image name from workflow - image=$(grep -E "^\s+image_name:" "$workflow" | head -1 | awk '{print $2}') + # Extract container name from directory + container=$(basename "$dir") + image="blumeops/$container" echo "📦 $container" echo " Image: $REGISTRY/$image" - echo " Workflow: $workflow" + echo " Path: $dir" # Query zot for recent tags tags=$(curl -sf "https://$REGISTRY/v2/$image/tags/list" 2>/dev/null | jq -r '.tags // [] | .[]' | grep -E '^v[0-9]' | sort -V | tail -4 || true) @@ -47,7 +39,7 @@ done echo "---" echo "To release a new version:" -echo " mise run container-release " +echo " mise run container-tag-and-release " echo "" echo "Example:" -echo " mise run container-release runner v1.0.0" +echo " mise run container-tag-and-release nettest v1.0.0" diff --git a/mise-tasks/container-release b/mise-tasks/container-tag-and-release similarity index 66% rename from mise-tasks/container-release rename to mise-tasks/container-tag-and-release index 9e8802b..6f37d4e 100755 --- a/mise-tasks/container-release +++ b/mise-tasks/container-tag-and-release @@ -7,7 +7,7 @@ CONTAINER="${1:-}" VERSION="${2:-}" if [[ -z "$CONTAINER" || -z "$VERSION" ]]; then - echo "Usage: mise run container-release " + echo "Usage: mise run container-tag-and-release " echo "" echo "Run 'mise run container-list' to see available containers and recent tags." exit 1 @@ -32,24 +32,23 @@ if git rev-parse "$TAG" >/dev/null 2>&1; then exit 1 fi -# Find the workflow file to determine image name -WORKFLOW_FILE=".forgejo/workflows/build-${CONTAINER}.yaml" -if [[ ! -f "$WORKFLOW_FILE" ]]; then - echo "Error: No workflow found for container '$CONTAINER'" +# Check if container directory exists +CONTAINER_DIR="containers/${CONTAINER}" +if [[ ! -f "$CONTAINER_DIR/Dockerfile" ]]; then + echo "Error: No Dockerfile found at '$CONTAINER_DIR/Dockerfile'" echo "" - echo "Run 'mise run container-list' to see available containers." + echo "Available containers:" + for dir in containers/*/; do + [[ -d "$dir" ]] && echo " - $(basename "$dir")" + done exit 1 fi -# Extract image name from workflow -IMAGE=$(grep -E "^\s+image_name:" "$WORKFLOW_FILE" | head -1 | awk '{print $2}') -if [[ -z "$IMAGE" ]]; then - echo "Error: Could not determine image name from $WORKFLOW_FILE" - exit 1 -fi +# Image name follows convention: blumeops/ +IMAGE="blumeops/${CONTAINER}" echo "Container: $CONTAINER" -echo "Workflow: $WORKFLOW_FILE" +echo "Directory: $CONTAINER_DIR" echo "Image: registry.tail8d86e.ts.net/$IMAGE:$VERSION" echo "" @@ -66,7 +65,7 @@ git tag "$TAG" git push origin "$TAG" echo "" -echo "✅ Tag '$TAG' created and pushed" +echo "Tag '$TAG' created and pushed" echo "" echo "The workflow will now build and push:" echo " registry.tail8d86e.ts.net/$IMAGE:$VERSION"