From ffd57730b6386d8650f0e14f7be9c540e4ab6dfb Mon Sep 17 00:00:00 2001 From: Farah Trigui Date: Mon, 9 Mar 2026 10:52:25 +0100 Subject: [PATCH 1/2] feat(): testing tuto capabilities in github actions --- .github/workflows/tuto-examples-test.yml | 220 +++++++++++++++++++ .github/workflows/validate_json_strucure.yml | 2 +- 2 files changed, 221 insertions(+), 1 deletion(-) create mode 100644 .github/workflows/tuto-examples-test.yml diff --git a/.github/workflows/tuto-examples-test.yml b/.github/workflows/tuto-examples-test.yml new file mode 100644 index 0000000..5884998 --- /dev/null +++ b/.github/workflows/tuto-examples-test.yml @@ -0,0 +1,220 @@ +name: Test tutorial steps + +on: + push: + branches: + - 'feat/automating-tuto-examples-testing' + paths: + - 'src/main/**' + - 'pom.xml' + workflow_dispatch: + +jobs: + test-tutorial: + runs-on: ubuntu-latest + env: + NOTION_API_KEY: ${{ secrets.NOTION_API_KEY }} + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Pull Naftiko Docker image + run: docker pull ghcr.io/naftiko/framework:latest + + - name: Run Naftiko - My First Capability + run: | + docker run -d \ + -p 8081:8081 \ + -v ${{ github.workspace }}/src/main/resources/schemas/tutorial/step-1-my-first-capability.yml:/app/step-1-my-first-capability.yml \ + --name naftiko_my_first_capability \ + ghcr.io/naftiko/framework:latest \ + /app/step-1-my-first-capability.yml + + - name: Wait for /hello endpoint - My First Capability + run: | + echo "Waiting for /hello endpoint..." + RESPONSE=$(curl -s -f --connect-timeout 5 --max-time 30 http://localhost:8081/hello || true) + if [[ -n "$RESPONSE" ]]; then + echo "My First Capability endpoint responded:" + echo "$RESPONSE" + else + echo "My First Capability endpoint did not respond in time" + docker logs naftiko_my_first_capability + exit 1 + fi + + - name: Show logs - My First Capability + if: always() + run: docker logs naftiko_my_first_capability + + - name: Stop container - My First Capability + if: always() + run: | + docker stop naftiko_my_first_capability + docker rm naftiko_my_first_capability + + - name: Run Naftiko - Forwarding API Resource + run: | + docker run -d \ + -p 8081:8081 \ + -v ${{ github.workspace }}/src/main/resources/schemas/tutorial/step-2-forwarding-api-resource.yml:/app/step-2-forwarding-api-resource.yml \ + --name naftiko_forwarding_api_resource \ + ghcr.io/naftiko/framework:latest \ + /app/step-2-forwarding-api-resource.yml + + - name: Wait for /notion/users/me endpoint - Forwarding API Resource + run: | + echo "Waiting for /notion/users/me endpoint..." + RESPONSE=$(curl -s -f --connect-timeout 5 --max-time 30 \ + -H "Authorization: Bearer $NOTION_API_KEY" \ + -H "Notion-Version: 2025-09-03" \ + http://localhost:8081/notion/users/me || true) + if [[ -n "$RESPONSE" ]]; then + echo "Forwarding API Resource endpoint responded:" + echo "$RESPONSE" + else + echo "Forwarding API Resource endpoint did not respond in time" + docker logs naftiko_forwarding_api_resource + exit 1 + fi + + - name: Show logs - Forwarding API Resource + if: always() + run: docker logs naftiko_forwarding_api_resource + + - name: Stop container - Forwarding API Resource + if: always() + run: | + docker stop naftiko_forwarding_api_resource + docker rm naftiko_forwarding_api_resource + + - name: Run Naftiko - Encapsulating Headers + run: | + docker run -d \ + -p 8081:8081 \ + -v ${{ github.workspace }}/src/main/resources/schemas/tutorial/step-3-encapsulating-headers.yml:/app/step-3-encapsulating-headers.yml \ + --env notion_api_key=$NOTION_API_KEY \ + --name naftiko_encapsulating_headers \ + ghcr.io/naftiko/framework:latest \ + /app/step-3-encapsulating-headers.yml + + - name: Wait for /notion/users/me endpoint - Encapsulating Headers + run: | + echo "Waiting for /notion/users/me endpoint..." + RESPONSE=$(curl -s -f --connect-timeout 5 --max-time 30 http://localhost:8081/notion/users/me || true) + if [[ -n "$RESPONSE" ]]; then + echo "Encapsulating Headers endpoint responded:" + echo "$RESPONSE" + else + echo "Encapsulating Headers endpoint did not respond in time" + docker logs naftiko_encapsulating_headers + exit 1 + fi + + - name: Show logs - Encapsulating Headers + if: always() + run: docker logs naftiko_encapsulating_headers + + - name: Stop container - Encapsulating Headers + if: always() + run: | + docker stop naftiko_encapsulating_headers + docker rm naftiko_encapsulating_headers + + - name: Run Naftiko - Filter Response + run: | + docker run -d \ + -p 8081:8081 \ + -v ${{ github.workspace }}/src/main/resources/schemas/tutorial/step-4-filter-reponse.yml:/app/step-4-filter-reponse.yml \ + --env notion_api_key=$NOTION_API_KEY \ + --name naftiko_filter_response \ + ghcr.io/naftiko/framework:latest \ + /app/step-4-filter-reponse.yml + + - name: Wait for /notion/users/me endpoint - Filter Response + run: | + echo "Waiting for /notion/users/me endpoint..." + RESPONSE=$(curl -s -f --connect-timeout 5 --max-time 30 http://localhost:8081/notion/users/me || true) + if [[ -n "$RESPONSE" ]]; then + echo "Filter Response endpoint responded:" + echo "$RESPONSE" + else + echo "Filter Response endpoint did not respond in time" + docker logs naftiko_filter_response + exit 1 + fi + + - name: Show logs - Filter Response + if: always() + run: docker logs naftiko_filter_response + + - name: Stop container - Filter Response + if: always() + run: | + docker stop naftiko_filter_response + docker rm naftiko_filter_response + + - name: Run Naftiko - Multi Steps + run: | + docker run -d \ + -p 8081:8081 \ + -v ${{ github.workspace }}/src/main/resources/schemas/tutorial/step-5-multi-steps.yml:/app/step-5-multi-steps.yml \ + --env notion_api_key=$NOTION_API_KEY \ + --name naftiko_multi_steps \ + ghcr.io/naftiko/framework:latest \ + /app/step-5-multi-steps.yml + + - name: Wait for /notion/my-full-user endpoint - Multi Steps + run: | + echo "Waiting for /notion/my-full-user endpoint..." + RESPONSE=$(curl -s -f --connect-timeout 5 --max-time 30 http://localhost:8081/notion/my-full-user || true) + if [[ -n "$RESPONSE" ]]; then + echo "Multi Steps endpoint responded:" + echo "$RESPONSE" + else + echo "Multi Steps endpoint did not respond in time" + docker logs naftiko_multi_steps + exit 1 + fi + + - name: Show logs - Multi Steps + if: always() + run: docker logs naftiko_multi_steps + + - name: Stop container - Multi Steps + if: always() + run: | + docker stop naftiko_multi_steps + docker rm naftiko_multi_steps + + - name: Run Naftiko - MCP Server + run: | + docker run -d \ + -p 9091:9091 \ + -v ${{ github.workspace }}/src/main/resources/schemas/tutorial/step-6-mcp.yml:/app/step-6-mcp.yml \ + --env notion_api_key=$NOTION_API_KEY \ + --name naftiko_mcp_server \ + ghcr.io/naftiko/framework:latest \ + /app/step-6-mcp.yml + + - name: Wait for MCP server - MCP Server + run: | + echo "Waiting for MCP server on port 9091..." + if nc -z -w30 localhost 9091; then + echo "MCP Server ready!" + else + echo "MCP Server did not start in time" + docker logs naftiko_mcp_server + exit 1 + fi + + - name: Show logs - MCP Server + if: always() + run: docker logs naftiko_mcp_server + + - name: Stop container - MCP Server + if: always() + run: | + docker stop naftiko_mcp_server + docker rm naftiko_mcp_server \ No newline at end of file diff --git a/.github/workflows/validate_json_strucure.yml b/.github/workflows/validate_json_strucure.yml index c765d5a..6500d13 100644 --- a/.github/workflows/validate_json_strucure.yml +++ b/.github/workflows/validate_json_strucure.yml @@ -5,7 +5,7 @@ on: paths: - 'src/main/resources/schemas/**' - '!src/main/resources/schemas/examples/**' - + workflow_dispatch: jobs: validate-schema: runs-on: ubuntu-latest From 4b2c6841af3e36b5a115a2600e504b20900fbc0e Mon Sep 17 00:00:00 2001 From: Farah Trigui Date: Tue, 10 Mar 2026 12:26:41 +0100 Subject: [PATCH 2/2] fix(): Trigger workflow test --- .github/workflows/tuto-examples-test.yml | 193 ++++++++++++----------- 1 file changed, 104 insertions(+), 89 deletions(-) diff --git a/.github/workflows/tuto-examples-test.yml b/.github/workflows/tuto-examples-test.yml index 5884998..871535e 100644 --- a/.github/workflows/tuto-examples-test.yml +++ b/.github/workflows/tuto-examples-test.yml @@ -1,9 +1,5 @@ -name: Test tutorial steps - on: push: - branches: - - 'feat/automating-tuto-examples-testing' paths: - 'src/main/**' - 'pom.xml' @@ -22,199 +18,218 @@ jobs: - name: Pull Naftiko Docker image run: docker pull ghcr.io/naftiko/framework:latest - - name: Run Naftiko - My First Capability + - name: Run Naftiko with My First Capability run: | docker run -d \ -p 8081:8081 \ -v ${{ github.workspace }}/src/main/resources/schemas/tutorial/step-1-my-first-capability.yml:/app/step-1-my-first-capability.yml \ - --name naftiko_my_first_capability \ + --name my_first_capability \ ghcr.io/naftiko/framework:latest \ /app/step-1-my-first-capability.yml - - name: Wait for /hello endpoint - My First Capability + - name: Consume /hello endpoint - My First Capability run: | - echo "Waiting for /hello endpoint..." - RESPONSE=$(curl -s -f --connect-timeout 5 --max-time 30 http://localhost:8081/hello || true) - if [[ -n "$RESPONSE" ]]; then - echo "My First Capability endpoint responded:" - echo "$RESPONSE" - else + # Wait for the Naftiko framework to fully start before hitting the endpoint + sleep 2 + RESPONSE=$(curl -s -f http://localhost:8081/hello || true) + if [[ -z "$RESPONSE" ]]; then echo "My First Capability endpoint did not respond in time" - docker logs naftiko_my_first_capability exit 1 fi + echo "Response: $RESPONSE" - name: Show logs - My First Capability if: always() - run: docker logs naftiko_my_first_capability + run: docker logs my_first_capability - - name: Stop container - My First Capability + - name: Stop My First Capability container if: always() run: | - docker stop naftiko_my_first_capability - docker rm naftiko_my_first_capability + docker stop my_first_capability + docker rm my_first_capability - - name: Run Naftiko - Forwarding API Resource + - name: Run Naftiko with Forwarding API Resource run: | docker run -d \ -p 8081:8081 \ -v ${{ github.workspace }}/src/main/resources/schemas/tutorial/step-2-forwarding-api-resource.yml:/app/step-2-forwarding-api-resource.yml \ - --name naftiko_forwarding_api_resource \ + --name forwarding_api_resource \ ghcr.io/naftiko/framework:latest \ /app/step-2-forwarding-api-resource.yml - - name: Wait for /notion/users/me endpoint - Forwarding API Resource + - name: Consume /notion/users/me endpoint - Forwarding API Resource run: | - echo "Waiting for /notion/users/me endpoint..." - RESPONSE=$(curl -s -f --connect-timeout 5 --max-time 30 \ + # Wait for the Naftiko framework to fully start before hitting the endpoint + sleep 2 + RESPONSE=$(curl -s -f \ -H "Authorization: Bearer $NOTION_API_KEY" \ -H "Notion-Version: 2025-09-03" \ http://localhost:8081/notion/users/me || true) - if [[ -n "$RESPONSE" ]]; then - echo "Forwarding API Resource endpoint responded:" - echo "$RESPONSE" - else + if [[ -z "$RESPONSE" ]]; then echo "Forwarding API Resource endpoint did not respond in time" - docker logs naftiko_forwarding_api_resource exit 1 fi + echo "Response: $RESPONSE" - name: Show logs - Forwarding API Resource if: always() - run: docker logs naftiko_forwarding_api_resource + run: docker logs forwarding_api_resource - - name: Stop container - Forwarding API Resource + - name: Stop Forwarding API Resource container if: always() run: | - docker stop naftiko_forwarding_api_resource - docker rm naftiko_forwarding_api_resource + docker stop forwarding_api_resource + docker rm forwarding_api_resource - - name: Run Naftiko - Encapsulating Headers + - name: Run Naftiko with Encapsulating Headers run: | docker run -d \ -p 8081:8081 \ -v ${{ github.workspace }}/src/main/resources/schemas/tutorial/step-3-encapsulating-headers.yml:/app/step-3-encapsulating-headers.yml \ --env notion_api_key=$NOTION_API_KEY \ - --name naftiko_encapsulating_headers \ + --name encapsulating_headers \ ghcr.io/naftiko/framework:latest \ /app/step-3-encapsulating-headers.yml - - name: Wait for /notion/users/me endpoint - Encapsulating Headers + - name: Consume /notion/users/me endpoint - Encapsulating Headers run: | - echo "Waiting for /notion/users/me endpoint..." - RESPONSE=$(curl -s -f --connect-timeout 5 --max-time 30 http://localhost:8081/notion/users/me || true) - if [[ -n "$RESPONSE" ]]; then - echo "Encapsulating Headers endpoint responded:" - echo "$RESPONSE" - else + # Wait for the Naftiko framework to fully start before hitting the endpoint + sleep 2 + RESPONSE=$(curl -s -f http://localhost:8081/notion/users/me || true) + if [[ -z "$RESPONSE" ]]; then echo "Encapsulating Headers endpoint did not respond in time" - docker logs naftiko_encapsulating_headers exit 1 fi + echo "Response: $RESPONSE" - name: Show logs - Encapsulating Headers if: always() - run: docker logs naftiko_encapsulating_headers + run: docker logs encapsulating_headers - - name: Stop container - Encapsulating Headers + - name: Stop Encapsulating Headers container if: always() run: | - docker stop naftiko_encapsulating_headers - docker rm naftiko_encapsulating_headers + docker stop encapsulating_headers + docker rm encapsulating_headers - - name: Run Naftiko - Filter Response + - name: Run Naftiko with Filter Response run: | docker run -d \ -p 8081:8081 \ -v ${{ github.workspace }}/src/main/resources/schemas/tutorial/step-4-filter-reponse.yml:/app/step-4-filter-reponse.yml \ --env notion_api_key=$NOTION_API_KEY \ - --name naftiko_filter_response \ + --name filter_response \ ghcr.io/naftiko/framework:latest \ /app/step-4-filter-reponse.yml - - name: Wait for /notion/users/me endpoint - Filter Response + - name: Consume /notion/users/me endpoint - Filter Response run: | - echo "Waiting for /notion/users/me endpoint..." - RESPONSE=$(curl -s -f --connect-timeout 5 --max-time 30 http://localhost:8081/notion/users/me || true) - if [[ -n "$RESPONSE" ]]; then - echo "Filter Response endpoint responded:" - echo "$RESPONSE" - else + # Wait for the Naftiko framework to fully start before hitting the endpoint + sleep 2 + RESPONSE=$(curl -s -f http://localhost:8081/notion/users/me || true) + if [[ -z "$RESPONSE" ]]; then echo "Filter Response endpoint did not respond in time" - docker logs naftiko_filter_response exit 1 fi + echo "Response: $RESPONSE" - name: Show logs - Filter Response if: always() - run: docker logs naftiko_filter_response + run: docker logs filter_response - - name: Stop container - Filter Response + - name: Stop Step - Filter Response if: always() run: | - docker stop naftiko_filter_response - docker rm naftiko_filter_response + docker stop filter_response + docker rm filter_response - - name: Run Naftiko - Multi Steps + - name: Run Naftiko with Multi Steps run: | docker run -d \ -p 8081:8081 \ -v ${{ github.workspace }}/src/main/resources/schemas/tutorial/step-5-multi-steps.yml:/app/step-5-multi-steps.yml \ --env notion_api_key=$NOTION_API_KEY \ - --name naftiko_multi_steps \ + --name multi_steps \ ghcr.io/naftiko/framework:latest \ /app/step-5-multi-steps.yml - - name: Wait for /notion/my-full-user endpoint - Multi Steps + - name: Consume /notion/my-full-user endpoint - Multi Steps run: | - echo "Waiting for /notion/my-full-user endpoint..." - RESPONSE=$(curl -s -f --connect-timeout 5 --max-time 30 http://localhost:8081/notion/my-full-user || true) - if [[ -n "$RESPONSE" ]]; then - echo "Multi Steps endpoint responded:" - echo "$RESPONSE" - else + # Wait for the Naftiko framework to fully start before hitting the endpoint + sleep 2 + RESPONSE=$(curl -s -f http://localhost:8081/notion/my-full-user || true) + if [[ -z "$RESPONSE" ]]; then echo "Multi Steps endpoint did not respond in time" - docker logs naftiko_multi_steps exit 1 fi + echo "Response: $RESPONSE" - name: Show logs - Multi Steps if: always() - run: docker logs naftiko_multi_steps + run: docker logs multi_steps - - name: Stop container - Multi Steps + - name: Stop Multi Steps container if: always() run: | - docker stop naftiko_multi_steps - docker rm naftiko_multi_steps + docker stop multi_steps + docker rm multi_steps - - name: Run Naftiko - MCP Server + - name: Run Naftiko with MCP Server run: | docker run -d \ -p 9091:9091 \ -v ${{ github.workspace }}/src/main/resources/schemas/tutorial/step-6-mcp.yml:/app/step-6-mcp.yml \ --env notion_api_key=$NOTION_API_KEY \ - --name naftiko_mcp_server \ + --name mcp_server \ ghcr.io/naftiko/framework:latest \ /app/step-6-mcp.yml - - name: Wait for MCP server - MCP Server + - name: Calling MCP server run: | - echo "Waiting for MCP server on port 9091..." - if nc -z -w30 localhost 9091; then - echo "MCP Server ready!" - else - echo "MCP Server did not start in time" - docker logs naftiko_mcp_server + # Wait for the Naftiko framework to fully start before hitting the endpoint + sleep 2 + if ! nc -z localhost 9091; then + echo "MCP server did not start in time" exit 1 fi - - - name: Show logs - MCP Server + echo "MCP server ready" + - name: Install yq + run: | + sudo wget -qO /usr/local/bin/yq https://github.com/mikefarah/yq/releases/latest/download/yq_linux_amd64 + sudo chmod +x /usr/local/bin/yq + - name: Test MCP tools/list + run: | + RESPONSE=$(curl -s -f -X POST http://localhost:9091 \ + -H "Content-Type: application/json" \ + -d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}' || true) + if [[ -z "$RESPONSE" ]]; then + echo "MCP tools/list did not respond" + exit 1 + fi + echo "Response: $RESPONSE" + CAPABILITY_FILE="${{ github.workspace }}/src/main/resources/schemas/tutorial/step-6-mcp.yml" + EXPECTED_COUNT=$(yq '.capability.exposes[0].tools | length' "$CAPABILITY_FILE") + EXPECTED_NAMES=$(yq '.capability.exposes[0].tools[].name' "$CAPABILITY_FILE") + ACTUAL_COUNT=$(echo "$RESPONSE" | jq '.result.tools | length') + if [[ "$ACTUAL_COUNT" != "$EXPECTED_COUNT" ]]; then + echo "Expected $EXPECTED_COUNT tool(s), got $ACTUAL_COUNT" + exit 1 + fi + while IFS= read -r EXPECTED_NAME; do + FOUND=$(echo "$RESPONSE" | jq -r --arg name "$EXPECTED_NAME" '.result.tools[] | select(.name == $name) | .name') + if [[ -z "$FOUND" ]]; then + echo "Expected tool '$EXPECTED_NAME' not found in response" + exit 1 + fi + done <<< "$EXPECTED_NAMES" + echo "tools/list validation passed: $ACTUAL_COUNT tool(s) matched" + + - name: Show logs MCP Server if: always() - run: docker logs naftiko_mcp_server + run: docker logs mcp_server - - name: Stop container - MCP Server + - name: Stop MCP Server container if: always() run: | - docker stop naftiko_mcp_server - docker rm naftiko_mcp_server \ No newline at end of file + docker stop mcp_server + docker rm mcp_server \ No newline at end of file