diff --git a/.github/workflows/build-push-sandbox.yml b/.github/workflows/build-push-sandbox.yml new file mode 100644 index 00000000..ead9b4b2 --- /dev/null +++ b/.github/workflows/build-push-sandbox.yml @@ -0,0 +1,139 @@ +name: Build and Push Project Sandbox Images + +on: + push: + branches: + - main + paths-ignore: + - "_assets/**" + - ".github/**" + - ".gitignore" + - ".gitmodules" + - ".typos.toml" + - "CODE-OF-CONDUCT.md" + - "CONTRIBUTING.md" + - "generate_sandbox_dockerfile.py" + - "generate_zenml_project.py" + - "LICENSE" + - "pyproject.toml" + - "README.md" + + workflow_dispatch: + inputs: + project: + description: "Project to build (leave empty to detect from changed files)" + required: false + default: "" + +jobs: + detect-changes: + runs-on: ubuntu-latest + outputs: + matrix: ${{ steps.set-matrix.outputs.matrix }} + steps: + - name: Checkout code + uses: actions/checkout@v3 + with: + fetch-depth: 2 + + - name: Detect changed projects + id: set-matrix + run: | + if [ "${{ github.event_name }}" == "workflow_dispatch" ]; then + if [ -n "${{ github.event.inputs.project }}" ]; then + PROJECTS="[\"${{ github.event.inputs.project }}\"]" + else + # Auto-detect changed files (same logic as push events) + CHANGED_FILES=$(git diff --name-only HEAD^ HEAD) + CHANGED_DIRS=$(echo "$CHANGED_FILES" | grep -o "^[^/]*" | sort -u | grep -v "^$") + ALL_PROJECT_DIRS=$(find . -maxdepth 1 -type d -not -path "*/\.*" -not -path "." | sed 's|^\./||' | grep -v "^_") + PROJECTS="[" + COMMA="" + for DIR in $CHANGED_DIRS; do + if echo "$ALL_PROJECT_DIRS" | grep -q "^$DIR$"; then + PROJECTS="${PROJECTS}${COMMA}\"${DIR}\"" + COMMA="," + fi + done + PROJECTS="${PROJECTS}]" + fi + else + CHANGED_FILES=$(git diff --name-only HEAD^ HEAD) + CHANGED_DIRS=$(echo "$CHANGED_FILES" | grep -o "^[^/]*" | sort -u | grep -v "^$") + ALL_PROJECT_DIRS=$(find . -maxdepth 1 -type d -not -path "*/\.*" -not -path "." | sed 's|^\./||' | grep -v "^_") + PROJECTS="[" + COMMA="" + for DIR in $CHANGED_DIRS; do + if echo "$ALL_PROJECT_DIRS" | grep -q "^$DIR$"; then + PROJECTS="${PROJECTS}${COMMA}\"${DIR}\"" + COMMA="," + fi + done + PROJECTS="${PROJECTS}]" + fi + echo "matrix=$PROJECTS" >> $GITHUB_OUTPUT + echo "Projects to build: $PROJECTS" + + build-and-push: + needs: detect-changes + runs-on: ubuntu-latest + strategy: + matrix: + project: ${{ fromJson(needs.detect-changes.outputs.matrix) }} + steps: + - name: Checkout code + uses: actions/checkout@v3 + with: + fetch-depth: 0 + token: ${{ secrets.GITHUB_TOKEN }} + + - name: Check for Dockerfile.sandbox + id: check-dockerfile + run: | + if [ -f "${{ matrix.project }}/Dockerfile.sandbox" ]; then + echo "dockerfile_exists=true" >> $GITHUB_OUTPUT + else + echo "dockerfile_exists=false" >> $GITHUB_OUTPUT + echo "No Dockerfile.sandbox found in ${{ matrix.project }}, will generate one." + fi + + - name: Set up Python + if: steps.check-dockerfile.outputs.dockerfile_exists == 'false' + uses: actions/setup-python@v4 + with: + python-version: "3.10" + + - name: Generate Dockerfile.sandbox if needed + if: steps.check-dockerfile.outputs.dockerfile_exists == 'false' + run: | + python generate_sandbox_dockerfile.py "${{ matrix.project }}" + echo "Generated Dockerfile.sandbox for ${{ matrix.project }}" + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v2 + + - name: Login to DockerHub + uses: docker/login-action@v2 + with: + username: ${{ secrets.DOCKERHUB_USERNAME }} + password: ${{ secrets.DOCKERHUB_PASSWORD }} + + - name: Build and push + uses: docker/build-push-action@v4 + with: + context: . + file: ${{ matrix.project }}/Dockerfile.sandbox + push: true + tags: | + safoinext/zenml-sandbox-${{ matrix.project }}:latest + cache-from: type=gha + cache-to: type=gha,mode=max + + - name: Commit Dockerfile if newly generated + if: steps.check-dockerfile.outputs.dockerfile_exists == 'false' + run: | + git config --local user.email "github-actions[bot]@users.noreply.github.com" + git config --local user.name "github-actions[bot]" + git add "${{ matrix.project }}/Dockerfile.sandbox" + git commit -m "Auto-generate Dockerfile.sandbox for ${{ matrix.project }}" + git push || echo "Failed to push changes, but Docker image was still built and pushed."