Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
84 changes: 84 additions & 0 deletions .github/scripts/analyze-workflow.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
#!/bin/bash
echo "=== KNIME Workflow Execution Summary ==="

# Get workflow information
if [ -f "/home/knime/workflow-info.env" ]; then
. /home/knime/workflow-info.env
WORKFLOW_NAME=$(basename "$WORKFLOW_DIR")
echo "Executed Workflow: $WORKFLOW_NAME"
echo "Workflow Location: $WORKFLOW_DIR"
else
echo "⚠ WARNING: Could not determine which workflow was executed"
WORKFLOW_NAME="Unknown"
fi

echo ""

if [ -f "/home/knime/workflow-console.log" ]; then
echo "Log file found, analyzing execution..."
LOG_FILE="/home/knime/workflow-console.log"

echo "Workflow Status:"
if grep -q "Workflow executed sucessfully" "$LOG_FILE" || grep -q "Workflow execution done" "$LOG_FILE"; then
echo "✓ SUCCESS: Workflow completed successfully"
elif grep -q "ERROR" "$LOG_FILE"; then
echo "✗ FAILED: Workflow execution failed"
else
echo "? UNKNOWN: Could not determine workflow status"
fi

echo ""
echo "Node Execution Summary:"
# Count nodes that finished execution
EXECUTED_NODES=$(grep -c "End execute" "$LOG_FILE" 2>/dev/null || echo "0")
echo "- Nodes executed: $EXECUTED_NODES"

# List executed nodes with timing
echo "- Executed nodes:"
grep "End execute" "$LOG_FILE" | sed 's/.*: / /' | sed 's/ End execute/ completed in/' || echo " None found"

echo ""
echo "Execution Timing:"
# Extract workflow execution time
WORKFLOW_TIME=$(grep "Workflow execution done" "$LOG_FILE" | sed -n 's/.*Finished in \([^)]*\).*/\1/p' || echo "Unknown")
echo "- Total workflow time: $WORKFLOW_TIME"

# Extract start and end times
START_TIME=$(grep "Executing workflow" "$LOG_FILE" | head -1 | cut -d' ' -f1-2 2>/dev/null || echo "Unknown")
END_TIME=$(grep "Workflow execution done" "$LOG_FILE" | tail -1 | cut -d' ' -f1-2 2>/dev/null || echo "Unknown")
echo "- Started: $START_TIME"
echo "- Completed: $END_TIME"

echo ""
echo "Issues Summary:"
# Count errors and warnings
ERROR_COUNT=$(grep -c ": ERROR :" "$LOG_FILE" 2>/dev/null || echo "0")
WARN_COUNT=$(grep -c ": WARN :" "$LOG_FILE" 2>/dev/null || echo "0")
echo "- Errors: $ERROR_COUNT"
echo "- Warnings: $WARN_COUNT"

# Show first error if any
if [ "$ERROR_COUNT" -gt 0 ]; then
echo ""
echo "First Error:"
grep ": ERROR :" "$LOG_FILE" | head -1 | sed 's/^/ /'
fi

# Show first warning if any
if [ "$WARN_COUNT" -gt 0 ]; then
echo ""
echo "First Warning:"
grep ": WARN :" "$LOG_FILE" | head -1 | sed 's/^/ /'
fi

echo ""
echo "Summary:"
echo "- Workflow: $WORKFLOW_NAME"
echo "- Log file location: $LOG_FILE"
echo "- Log file size: $(du -h "$LOG_FILE" | cut -f1)"
else
echo "⚠ WARNING: No log file found at expected location"
echo "Checking for alternative log locations..."
find /home/knime -name "*.log" -type f 2>/dev/null | head -10
fi
echo "============================================"
59 changes: 59 additions & 0 deletions .github/workflows/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
# Define the base image
FROM public.ecr.aws/i0n0z6j1/knime:5.7.0-nightly

# Path inside the image where the local update site will be copied
ARG LOCAL_UPDATE_SITE_PATH=/home/knime/local-update-site
ARG LOCAL_UPDATE_SITE_SRC
ENV LOCAL_UPDATE_SITE_SRC=${LOCAL_UPDATE_SITE_SRC}

# Define the list of update sites and features
# Add the local update site (copied into the image) to the list of update sites via file:// URL
# Ensure the local update site is present in the build context under ./local-update-site
ENV KNIME_UPDATE_SITES="file://${LOCAL_UPDATE_SITE_PATH}, https://update.knime.com/analytics-platform/nightly"

# Install features from the update sites
# Allow overriding via build-arg; fallback to a sensible default matching knime.yml (group_id + ".features." + name)
ARG KNIME_FEATURES_ARG
ENV KNIME_FEATURES="${KNIME_FEATURES_ARG:-org.tutorial.features.first_extension.feature.group}"

# Install CA Certificates
USER root
RUN apt-get update && \
apt-get install -y ca-certificates chromium-browser unzip && \
update-ca-certificates && \
rm -rf /var/lib/apt/lists/*

USER knime

# Copy the local update site produced by the build into the image so it's available during installation
# The source folder can be overridden via --build-arg LOCAL_UPDATE_SITE_SRC=...
COPY --chown=knime:knime ${LOCAL_UPDATE_SITE_SRC} ${LOCAL_UPDATE_SITE_PATH}

# Execute extension installation script
RUN ./install-extensions.sh

# pre-start executor to improve startup time
RUN KNIME_EXECUTOR_CONNECTION_RETRIES=0 knime/knime -data /home/knime/knime-workspace -consolelog -nosplash -application com.knime.enterprise.slave.KNIME_REMOTE_APPLICATION; rm -rf /home/knime/knime-workspace

# Copy the demo workflow into the image
COPY --chown=knime:knime demo/ /home/knime/demo-workflow/

# Find and unzip the first .knwf file in the demo folder
RUN KNWF_FILE=$(find /home/knime/demo-workflow -name "*.knwf" -type f | head -1) && \
if [ -z "$KNWF_FILE" ]; then \
echo "ERROR: No .knwf file found in demo folder" && exit 1; \
fi && \
WORKFLOW_NAME=$(basename "$KNWF_FILE" .knwf) && \
echo "Found workflow: $KNWF_FILE" && \
echo "Extracting to: /home/knime/demo-workflow/$WORKFLOW_NAME" && \
unzip "$KNWF_FILE" -d "/home/knime/demo-workflow/$WORKFLOW_NAME" && \
echo "WORKFLOW_DIR=/home/knime/demo-workflow/$WORKFLOW_NAME" > /home/knime/workflow-info.env

# Copy the workflow analysis script
COPY --chown=knime:knime .github/scripts/analyze-workflow.sh /home/knime/analyze-workflow.sh
RUN chmod +x /home/knime/analyze-workflow.sh

# Run the demo workflow to test the extension
RUN . /home/knime/workflow-info.env && \
echo "Running workflow from: $WORKFLOW_DIR" && \
knime/knime -reset -consolelog -nosplash -application org.knime.product.KNIME_BATCH_APPLICATION -workflowDir="$WORKFLOW_DIR" > /home/knime/workflow-console.log 2>&1
105 changes: 105 additions & 0 deletions .github/workflows/run_knime_workflow_test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
name: 'Run KNIME Workflow Test'

on:
workflow_dispatch:
inputs:
run_build:
description: 'Run build job'
required: false
default: 'true'
pull_request:
types: [opened, synchronize, reopened]
push:
branches: [ master ]

jobs:
build:
name: Bundle extension and build image
runs-on: ubuntu-latest
if: ${{ github.event_name != 'workflow_dispatch' || github.event.inputs.run_build == 'true' }}
env:
LOCAL_UPDATE_SITE_DIR: local-update-site
steps:
- name: Checkout repository
uses: actions/checkout@v4

- name: Setup Pixi
uses: prefix-dev/setup-pixi@v0

- name: Install environment
run: pixi install

- name: Build local update site
run: pixi run build

- name: Upload update site artifact
uses: actions/upload-artifact@v4
with:
name: extensionartifacts-for-update-site-${{ github.run_id }}
path: ${{ env.LOCAL_UPDATE_SITE_DIR }}

- name: Compute KNIME feature group from knime.yml
id: knime_meta
shell: bash
run: |
pixi run -e build python - <<'PY'
import os
import yaml
with open('knime.yml', 'r', encoding='utf-8') as f:
y = yaml.safe_load(f)
group_id = (y.get('group_id') or '').strip()
name = (y.get('name') or '').strip()
if not group_id or not name:
raise SystemExit(f"Failed to parse group_id/name from knime.yml (group_id={group_id}, name={name})")
feature_group_id = f"{group_id}.features.{name}.feature.group"
with open(os.environ['GITHUB_OUTPUT'], 'a', encoding='utf-8') as gh:
print(f"feature_group_id={feature_group_id}", file=gh)
print("Computed feature group:", feature_group_id)
PY

- name: Build KNIME image with local update site
run: |
docker build \
-f .github/workflows/Dockerfile \
--build-arg LOCAL_UPDATE_SITE_SRC="${{ env.LOCAL_UPDATE_SITE_DIR }}" \
--build-arg KNIME_FEATURES_ARG="${{ steps.knime_meta.outputs.feature_group_id }}" \
-t knime-executor-with-extension:ci .

- name: Analyze workflow execution results
id: workflow_analysis
run: |
echo "Extracting workflow execution results..."
ANALYSIS_OUTPUT=$(docker run --rm knime-executor-with-extension:ci /home/knime/analyze-workflow.sh)
echo "$ANALYSIS_OUTPUT"

# Extract key metrics for badge
EXECUTED_NODES=$(echo "$ANALYSIS_OUTPUT" | grep "Nodes executed:" | sed 's/.*: //')
ERROR_COUNT=$(echo "$ANALYSIS_OUTPUT" | grep "Errors:" | sed 's/.*: //')

# Determine badge status
if echo "$ANALYSIS_OUTPUT" | grep -q "SUCCESS"; then
if [ "$ERROR_COUNT" = "0" ]; then
BADGE_MESSAGE="workflow passed-${EXECUTED_NODES} nodes"
BADGE_COLOR="brightgreen"
else
BADGE_MESSAGE="workflow passed-${EXECUTED_NODES} nodes, ${ERROR_COUNT} errors"
BADGE_COLOR="yellow"
fi
else
BADGE_MESSAGE="workflow failed"
BADGE_COLOR="red"
fi

echo "badge_message=$BADGE_MESSAGE" >> $GITHUB_OUTPUT
echo "badge_color=$BADGE_COLOR" >> $GITHUB_OUTPUT
echo "executed_nodes=$EXECUTED_NODES" >> $GITHUB_OUTPUT
echo "error_count=$ERROR_COUNT" >> $GITHUB_OUTPUT

- name: Update workflow status badge
if: github.ref == 'refs/heads/master'
run: |
# Create badge URL that you can use in README
BADGE_URL="https://img.shields.io/badge/${{ steps.workflow_analysis.outputs.badge_message }}-${{ steps.workflow_analysis.outputs.badge_color }}"
echo "Badge URL: $BADGE_URL"
echo "You can use this in your README.md:"
echo "![Workflow Status]($BADGE_URL)"
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# ![Image](https://www.knime.com/sites/default/files/knime_logo_github_40x40_4layers.png) KNIME® - KNIME PYTHON EXTENSION TEMPLATE

[![CI](https://github.com/knime/knime-python-extension-template/actions/workflows/ci.yml/badge.svg)](https://github.com/knime/knime-python-extension-template/actions/workflows/ci.yml)
[![Workflow Test](https://github.com/marc-lehner/knime-python-extension-template/actions/workflows/run_knime_workflow_test.yml/badge.svg)](https://github.com/marc-lehner/knime-python-extension-template/actions/workflows/run_knime_workflow_test.yml)

This repository is maintained by the [KNIME Team Rakete](mailto:team-rakete@knime.com).

Expand Down
Loading