Replace feedback files with OpenAPI Overlays [BLOCKED] #198
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Generate Arazzo Spec from Jentic OpenAPI URL in Issue | |
| on: | |
| issues: | |
| types: [ opened ] | |
| jobs: | |
| generate-arazzo: | |
| if: contains(github.event.issue.body, 'openapi_url:') | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: write | |
| pull-requests: write | |
| issues: write | |
| steps: | |
| - name: Check out the repository | |
| uses: actions/checkout@v4 | |
| - name: Extract OpenAPI URL and Details from issue body | |
| id: extract_info | |
| run: | | |
| echo "Parsing OpenAPI URL and details from issue..." | |
| BODY="${{ github.event.issue.body }}" | |
| URL=$(echo "$BODY" | grep -oP '(?<=openapi_url:).*' | head -n 1 | xargs) | |
| # Attempt to extract vendor and api_name from URL structure | |
| # Example: .../apis/openapi/vendor.com/api_name/version/openapi.json | |
| VENDOR_NAME=$(echo "$URL" | grep -oP '(?<=apis/openapi/)[^/]+' | head -n 1) | |
| API_NAME=$(echo "$URL" | grep -oP '(?<=apis/openapi/'"$VENDOR_NAME"'/)[^/]+' | head -n 1) | |
| # Extract version from the part right before openapi.json | |
| API_VERSION=$(echo "$URL" | grep -oP '[^/]+(?=/openapi\.json)' | head -n 1) | |
| # Extract Workflow Descriptions section as a JSON array | |
| # Looks for the specific heading from the issue template | |
| WORKFLOW_DESCRIPTIONS=$(echo "$BODY" | awk '/^### Workflow Descriptions \(Optional\)/{flag=1;next}/^## |^### /{if(flag)flag=0}flag' | grep -E '^[-*] ' | sed -E 's/^[-*] *//' | jq -R . | jq -sc .) | |
| if [ -z "$URL" ]; then | |
| echo "::error::Could not extract openapi_url from issue body." | |
| exit 1 | |
| fi | |
| if [ -z "$VENDOR_NAME" ]; then | |
| echo "::warning::Could not automatically determine VENDOR_NAME from URL: $URL. Defaulting path." | |
| VENDOR_NAME="unknown-vendor-${{ github.event.issue.number }}" | |
| fi | |
| if [ -z "$API_NAME" ]; then | |
| # Assume 'main' if api_name part is missing or different structure | |
| echo "::warning::Could not automatically determine API_NAME from URL: $URL. Assuming 'main'." | |
| API_NAME="main" | |
| fi | |
| if [ -z "$API_VERSION" ]; then | |
| # Assume 'latest' if version part is missing or different structure | |
| echo "::warning::Could not automatically determine API_VERSION from URL: $URL. Assuming 'latest'." | |
| API_VERSION="latest" | |
| fi | |
| echo "Extracted URL: $URL" | |
| echo "Determined Vendor: $VENDOR_NAME" | |
| echo "Determined API Name: $API_NAME" | |
| echo "Determined API Version: $API_VERSION" | |
| echo "Extracted Workflow Descriptions: $WORKFLOW_DESCRIPTIONS" | |
| echo "openapi_url=$URL" >> $GITHUB_OUTPUT | |
| echo "vendor_name=$VENDOR_NAME" >> $GITHUB_OUTPUT | |
| echo "api_name=$API_NAME" >> $GITHUB_OUTPUT | |
| echo "api_version=$API_VERSION" >> $GITHUB_OUTPUT | |
| echo "workflow_descriptions=$WORKFLOW_DESCRIPTIONS" >> $GITHUB_OUTPUT | |
| - name: Call Arazzo Generator API and Create File | |
| id: call_api_and_create_file | |
| run: | | |
| echo "Calling Arazzo Generator API with OpenAPI URL: ${{ steps.extract_info.outputs.openapi_url }}" | |
| # Prepare workflow_descriptions JSON for curl | |
| WF_DESCRIPTIONS='${{ steps.extract_info.outputs.workflow_descriptions }}' | |
| if [ "$WF_DESCRIPTIONS" = "" ] || [ "$WF_DESCRIPTIONS" = "null" ] || [ "$WF_DESCRIPTIONS" = "[]" ]; then | |
| WF_DESCRIPTIONS=null | |
| fi | |
| RESPONSE=$(jq -n --arg url "${{ steps.extract_info.outputs.openapi_url }}" \ | |
| --arg format "json" \ | |
| --argjson validate_spec true \ | |
| --argjson direct_llm false \ | |
| --rawfile wf_desc <(echo "$WF_DESCRIPTIONS") \ | |
| '{url: $url, format: $format, validate_spec: $validate_spec, direct_llm: $direct_llm, workflow_descriptions: ($wf_desc | fromjson? // null)}' | \ | |
| curl -v --show-error -X POST https://arazzo-runner.main.us-east-1.jenticprod.net/generate \ | |
| -H "Content-Type: application/json" \ | |
| -d @-) | |
| # Determine output directory structure based on vendor/api name | |
| VENDOR="${{ steps.extract_info.outputs.vendor_name }}" | |
| API="${{ steps.extract_info.outputs.api_name }}" | |
| if [ "$API" == "main" ] || [ -z "$API" ]; then | |
| TARGET_SUBDIR="$VENDOR" | |
| else | |
| TARGET_SUBDIR="${VENDOR}~${API}" | |
| fi | |
| # Define the target file path within the current repository | |
| TARGET_DIR="workflows/$TARGET_SUBDIR" | |
| SPEC_FILE="$TARGET_DIR/workflows.arazzo.json" | |
| echo "Target spec file: $SPEC_FILE" | |
| # Ensure the target directory exists | |
| mkdir -p "$TARGET_DIR" | |
| # Attempt to parse and save the spec file | |
| if ! echo "$RESPONSE" | jq -e '.arazzo_spec' > "$SPEC_FILE"; then | |
| echo "::error::API call failed or API response did not contain expected '.arazzo_spec' field." | |
| echo "Response was:" | |
| echo "$RESPONSE" | |
| echo "api_failed=true" >> $GITHUB_OUTPUT | |
| echo "error_response=$RESPONSE" >> $GITHUB_OUTPUT | |
| exit 1 | |
| fi | |
| # Extract fallback status/message if custom workflow descriptions failed and caused regeneration | |
| FALLBACK_USED=$(echo "$RESPONSE" | jq -r '.fallback_used // false') | |
| FALLBACK_MSG=$(echo "$RESPONSE" | jq -r '.message // empty') | |
| # Build a note for the PR body | |
| # If the fallback regeneration logic is used after custom workflow descriptions failed to generate arazzo file then add a warning note | |
| if [ "$FALLBACK_USED" = true ]; then | |
| NOTE="**⚠️ WARNING:** $FALLBACK_MSG" | |
| else | |
| NOTE="" | |
| fi | |
| echo "fallback_note=$NOTE" >> "$GITHUB_OUTPUT" | |
| echo "API call successful, $SPEC_FILE created in workspace." | |
| # --- Debugging: Verify file --- (Run within the context of the workspace) | |
| echo "--- Debug: Checking created file ---" | |
| ls -la "$TARGET_DIR" | |
| echo "Content of $SPEC_FILE (first 5 lines):" | |
| head -n 5 "$SPEC_FILE" || echo "WARN: Could not read head of $SPEC_FILE" | |
| echo "--- End Debugging ---" | |
| # Optional: Check git status within the repository | |
| - name: Check Git Status Before PR Action | |
| run: | | |
| echo "--- Debug: Git Status ---" | |
| git status | |
| echo "--- End Debug Status ---" | |
| - name: Create Pull Request | |
| uses: peter-evans/create-pull-request@v6 | |
| with: | |
| token: ${{ secrets.GITHUB_TOKEN }} | |
| # No 'path' needed, operates on the whole repo | |
| commit-message: "feat: Add Arazzo spec for ${{ steps.extract_info.outputs.vendor_name }}/${{ steps.extract_info.outputs.api_name }}/${{ steps.extract_info.outputs.api_version }} (Issue #${{ github.event.issue.number }})" | |
| title: "feat: Add Arazzo spec for ${{ steps.extract_info.outputs.vendor_name }}/${{ steps.extract_info.outputs.api_name }}/${{ steps.extract_info.outputs.api_version }} (Issue #${{ github.event.issue.number }})" | |
| body: | | |
| This PR adds the Arazzo spec generated for the OpenAPI URL provided in Issue #${{ github.event.issue.number }} to Jentic OAK. | |
| **Vendor:** ${{ steps.extract_info.outputs.vendor_name }} | |
| **API Name:** ${{ steps.extract_info.outputs.api_name }} | |
| **API Version:** ${{ steps.extract_info.outputs.api_version }} | |
| **Source URL:** ${{ steps.extract_info.outputs.openapi_url }} | |
| Arazzo spec was automatically generated by the hosted API. | |
| ${{ steps.call_api_and_create_file.outputs.fallback_note }} | |
| Closes #${{ github.event.issue.number }} | |
| branch: feat/arazzo-${{ steps.extract_info.outputs.vendor_name }}-${{ steps.extract_info.outputs.api_name }}-${{ steps.extract_info.outputs.api_version }}-${{ github.event.issue.number }} | |
| base: main # Or your target branch in jentic-arazzo-generator | |
| # Optional: Add labels, assignees etc. | |
| # labels: automated-pr, arazzo-spec | |
| - name: Comment on Issue if API Failed | |
| if: failure() && steps.call_api_and_create_file.outputs.api_failed == 'true' | |
| uses: actions/github-script@v7 | |
| with: | |
| github-token: ${{ secrets.GITHUB_TOKEN }} | |
| script: | | |
| const errorResponse = `${{ steps.call_api_and_create_file.outputs.error_response }}`; | |
| let errorMessage = "❌ **Failed to generate Arazzo specification**\n\n"; | |
| try { | |
| const response = JSON.parse(errorResponse); | |
| if (response.error) { | |
| errorMessage += `**Error:** ${response.error}\n\n`; | |
| } | |
| if (response.message) { | |
| errorMessage += `**Details:** ${response.message}\n\n`; | |
| } | |
| if (response.validation_errors && response.validation_errors.length > 0) { | |
| errorMessage += `**Validation Errors:**\n`; | |
| response.validation_errors.forEach(error => { | |
| errorMessage += `- ${error}\n`; | |
| }); | |
| errorMessage += "\n"; | |
| } | |
| } catch (e) { | |
| errorMessage += `**Raw Response:** \`\`\`\n${errorResponse}\n\`\`\`\n\n`; | |
| } | |
| errorMessage += "There was an error generating the Arazzo spec from the provided OpenAPI specification URL.\n\n"; | |
| errorMessage += "If you believe this is a bug with the Arazzo generator or need additional support, please contact the development team at Jentic Community Discord (https://discord.gg/yrxmDZWMqB).\n\n"; | |
| errorMessage += "Alternatively create a new issue reporting the bug (https://github.com/jentic/jentic-public-apis/issues/new?template=BLANK_ISSUE)."; | |
| github.rest.issues.createComment({ | |
| issue_number: context.issue.number, | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| body: errorMessage | |
| }); |