Skip to content

feat: Dynamic Feed-In Pricing with Multi-Source Support (Issue #219) #298

feat: Dynamic Feed-In Pricing with Multi-Source Support (Issue #219)

feat: Dynamic Feed-In Pricing with Multi-Source Support (Issue #219) #298

name: Develop - build image and push
# This workflow builds, tests, and pushes a Docker image to GitHub Container Registry.
# It is triggered on pushes and pull requests to the "develop" branch, and can also be triggered manually.
# The image is tagged with "develop" and a version string based on the workflow run number.
# For pull requests, the Docker image is uploaded as an artifact instead of being pushed to the registry.
# After publishing, old Docker images with the "develop" version suffix are cleaned up to save space.
# Orphaned untagged SHA manifests (architecture-specific child manifests of deleted versions) are also
# cleaned up, while preserving those still referenced by the kept tagged versions.
# The workflow uses the GITHUB_TOKEN secret for authentication with GitHub Container Registry.
# Jobs:
# - pytest: Runs unit and regression tests using pytest.
# - build_image: Builds the Docker image, tags it, and uploads it as an artifact for PRs.
# - publish_image: Downloads the image artifact and pushes it to GitHub Container Registry (on push events).
# - cleanup_old_develops: Cleans up old "develop" tagged images and orphaned SHA manifests (on push events).
on:
push:
branches: ["develop"]
# pull_request:
# branches: ["develop"]
workflow_dispatch: # allows manual triggering of the workflow
env:
VERSION_PREFIX: 0.3.35.
VERSION_SUFFIX: -develop
jobs:
pytest:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v6
- name: Set up Python
uses: actions/setup-python@v6
with:
python-version: "3.13"
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install -r requirements.txt
pip install pytest
- name: Run unit and regression tests
run: python -m pytest -v tests/
publish_image:
runs-on: ubuntu-latest
needs: pytest
steps:
- name: Checkout
uses: actions/checkout@v6
- name: Pull latest changes
run: git pull origin develop --rebase
- name: Set version string
run: echo "VERSION=${{ env.VERSION_PREFIX }}${{ github.run_number }}${{env.VERSION_SUFFIX}}" >> $GITHUB_ENV
- name: Write version to file
run: echo "__version__ = '${{ env.VERSION }}'" > src/version.py
- name: Commit version file and push changes
if: github.event_name == 'push'
uses: devops-infra/action-commit-push@master
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
commit_prefix: "[AUTO] "
commit_message: "Update version to ${{ env.VERSION }}"
- name: Convert repository owner to lowercase
run: echo "owner=$(echo '${{ github.repository_owner }}' | tr '[:upper:]' '[:lower:]')" >> $GITHUB_ENV
# 1. Setup QEMU for ARM64 emulation
- name: Set up QEMU
uses: docker/setup-qemu-action@v3
with:
platforms: all
# 2. Setup Buildx
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
# 3. Log in to GitHub Container Registry
- name: Log in to GitHub Container Registry
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
# 4. Build & Push Multi-Arch Image
- name: Build and push multi-platform Docker image
uses: docker/build-push-action@v5
with:
context: .
platforms: linux/amd64,linux/arm64
provenance: false
sbom: false
tags: |
ghcr.io/${{ env.owner }}/eos_connect:develop
ghcr.io/${{ env.owner }}/eos_connect:${{ env.VERSION }}
push: ${{ github.event_name == 'push' }}
- name: Upload Docker image as artifact
if: github.event_name == 'pull_request'
uses: actions/upload-artifact@v4
with:
name: eos_connect_image-${{ env.VERSION }}
path: eos_connect_${{ env.VERSION }}.tar.gz
cleanup_old_develops:
needs: publish_image
runs-on: ubuntu-latest
steps:
- name: Convert repository owner to lowercase
run: echo "owner=$(echo '${{ github.repository_owner }}' | tr '[:upper:]' '[:lower:]')" >> $GITHUB_ENV
- name: Cleanup old tagged versions and their child SHA manifests
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
PACKAGE="eos_connect"
REGISTRY="ghcr.io"
IMAGE="$REGISTRY/${{ env.owner }}/$PACKAGE"
echo "$GH_TOKEN" | docker login $REGISTRY -u "${{ github.actor }}" --password-stdin
ALL_VERSIONS=$(gh api --paginate /user/packages/container/$PACKAGE/versions | jq -s 'flatten')
# Build a digest->id lookup map from all untagged versions for fast child resolution
SHA_TO_ID=$(echo "$ALL_VERSIONS" | jq -r '.[] | select(.metadata.container.tags | length == 0) | "\(.name) \(.id)"')
# Select old tagged develop versions to delete (keep latest 3), oldest first
OLD_TAGGED=$(echo "$ALL_VERSIONS" | jq -r '[.[] | select(.metadata.container.tags | map(endswith("${{ env.VERSION_SUFFIX }}")) | any)] | sort_by(.created_at) | reverse | .[3:][] | "\(.id)|\(.metadata.container.tags[0])"')
while IFS= read -r entry; do
[ -z "$entry" ] && continue
vid=$(echo "$entry" | cut -d'|' -f1)
tag=$(echo "$entry" | cut -d'|' -f2)
echo "Removing version: $tag (id: $vid)"
# Resolve child SHA manifests before deleting the parent tag
CHILD_SHAS=$(docker manifest inspect "$IMAGE:$tag" 2>/dev/null \
| jq -r '(.manifests // []) | .[].digest' 2>/dev/null || echo "")
# Delete the tagged parent first
gh api -X DELETE /user/packages/container/$PACKAGE/versions/$vid
# Delete all child SHA manifests immediately
for sha in $CHILD_SHAS; do
child_id=$(echo "$SHA_TO_ID" | grep "^$sha " | awk '{print $2}')
if [ -n "$child_id" ]; then
echo " Deleting child SHA: $sha (id: $child_id)"
gh api -X DELETE /user/packages/container/$PACKAGE/versions/$child_id
fi
done
done <<< "$OLD_TAGGED"
echo "=== Cleanup complete ==="