# .gitea/workflows/openapi.yml name: OpenAPI evaluation on: push: branches: - main pull_request: branches: - main paths: - 'docs/*/openapi/*.yaml' - 'docs/*/openapi/*.yml' jobs: openapi: runs-on: ubuntu-latest steps: - name: Checkout repository uses: actions/checkout@v4 with: fetch-depth: 0 - name: Dump Gitea env run: | env | sort | grep GITEA - name: Get base branch name id: base run: | base_ref=$(jq -r '.pull_request.base.ref' "$GITEA_PATH") echo "base_ref=$base_ref" echo "${{ gitea.base_ref }}" BASE_SHA="${{ gitea.event.pull_request.base.sha }}" echo "Base SHA: $BASE_SHA" - name: Get changed files other method id: changed-files run: | BASE_SHA="${{ gitea.event.pull_request.base.sha }}" echo "Base SHA: $BASE_SHA" git fetch origin $BASE_SHA echo "changed_files=$(git diff --name-only ${BASE_SHA}...HEAD | grep -E '^docs/[^/]+/openapi/.*\.(yaml|yml)$' | xargs)" >> $GITHUB_OUTPUT - name: List changed files run: | for file in ${{ steps.changed-files.outputs.changed_files }}; do echo "$file was changed" done - name: Get changed OpenAPI files (branch URLs) id: changed-urls run: | BASE_SHA="${{ gitea.event.pull_request.base.sha }}" git fetch origin $BASE_SHA # Use PR branch if available, otherwise push branch BRANCH="${{ gitea.head_ref }}" if [ -z "$BRANCH" ]; then BRANCH="${{ gitea.ref_name }}" fi REPO_URL="${{ gitea.server_url }}/${{ gitea.repository }}" # Only docs/*/openapi/*.yaml or yml # FILES=$(git diff --name-only ${BASE_SHA}...HEAD \ # | grep -E '^docs/[^/]+/openapi/.*\.(yaml|yml)$' || true) echo "changed urls" for file in ${{ steps.changed-files.outputs.changed_files }}; do echo "$REPO_URL/raw/branch/$BRANCH/$file" done echo "changed_urls<> $GITHUB_OUTPUT for file in ${{ steps.changed-files.outputs.changed_files }}; do echo "$REPO_URL/raw/branch/$BRANCH/$file" done >> $GITHUB_OUTPUT echo "EOF" >> $GITHUB_OUTPUT - name: List URLs run: | while IFS= read -r url; do echo "$url was changed" done <<< "${{ steps.changed-urls.outputs.changed_urls }}" - name: Validate OpenAPI files + show validation results env: INTERNAL_OPENAPI_KEY: ${{ secrets.INTERNAL_OPENAPI_KEY }} API_URL: ${{ vars.OPENAPI_URL }} REPORTPORTAL_URL: ${{ vars.REPORTPORTAL_URL }} run: | set -e MAX_ATTEMPTS=30 # ~5 minutes total (30 * 10s) SLEEP_SECONDS=10 HAS_FAILURE=0 # <-- track failures # --- Fetching access token --- OPENAPI_TOKEN="$(curl -X POST "https://${API_URL}/api/token/machine" \ -H "X-Internal-Api-Key: $INTERNAL_OPENAPI_KEY" | jq -r .access_token)" echo "::add-mask::$OPENAPI_TOKEN" while IFS= read -r url; do [ -z "$url" ] && continue echo "==============================" echo "Validating: $url" # --- 1. trigger validation using file_content --- VALIDATION_RESPONSE=$(curl -sS -X POST "https://${API_URL}/api/validate" \ -H "Content-Type: application/json" \ -H "Authorization: Bearer $OPENAPI_TOKEN" \ -d "$(jq -n \ --arg path "$url" \ '{path: $path, export: "xml", ruleset: "default"}')") echo "Validation response:" echo "$VALIDATION_RESPONSE" # --- 2. extract launch id --- LAUNCH_UUID=$(echo "$VALIDATION_RESPONSE" | jq -r '.launch.id // empty') if [ -z "$LAUNCH_UUID" ]; then echo "❌ Could not extract launch UUID" HAS_FAILURE=1 continue fi echo "Launch UUID: $LAUNCH_UUID" # --- 3. wait until validation finishes --- ATTEMPT=1 STATUS="IN_PROGRESS" while [ "$STATUS" = "IN_PROGRESS" ] && [ $ATTEMPT -le $MAX_ATTEMPTS ]; do echo "Checking launch status (attempt $ATTEMPT/$MAX_ATTEMPTS)..." LAUNCH_DETAILS=$(curl -sS \ -H "Authorization: Bearer $OPENAPI_TOKEN" \ "https://${API_URL}/api/reportportal?project=openapi&launchId=$LAUNCH_UUID") STATUS=$(echo "$LAUNCH_DETAILS" | jq -r '.status // "UNKNOWN"') echo "Current status: $STATUS" if [ "$STATUS" = "IN_PROGRESS" ]; then sleep $SLEEP_SECONDS fi ATTEMPT=$((ATTEMPT+1)) done if [ "$STATUS" = "IN_PROGRESS" ]; then echo "⚠️ Timeout waiting for validation to finish" HAS_FAILURE=1 continue fi # --- 4. extract statistics --- STATUS=$(echo "$LAUNCH_DETAILS" | jq -r '.status') TOTAL=$(echo "$LAUNCH_DETAILS" | jq -r '.statistics.executions.total') PASSED=$(echo "$LAUNCH_DETAILS" | jq -r '.statistics.executions.passed') FAILED=$(echo "$LAUNCH_DETAILS" | jq -r '.statistics.executions.failed') SKIPPED=$(echo "$LAUNCH_DETAILS" | jq -r '.statistics.executions.skipped') if [ "$STATUS" = "FAILED" ]; then echo "❌ Validation FAILED for $url" HAS_FAILURE=1 fi # Fetch Launch ID LAUNCH_ID=$(echo "$LAUNCH_DETAILS" | jq -r '.id') # fallback if API doesn't return UI link REPORT_URL="https://${REPORTPORTAL_URL}/ui/#openapi/launches/all/$LAUNCH_ID" # --- 5. summary --- echo "" echo "📊 Validation summary" echo "Status: $STATUS" echo "Total: $TOTAL" echo "Passed: $PASSED" echo "Failed: $FAILED" echo "Skipped: $SKIPPED" echo "Report: $REPORT_URL" echo "==============================" echo done <<< "${{ steps.changed-urls.outputs.changed_urls }}" if [ "$HAS_FAILURE" -eq 1 ]; then echo "❌ One or more OpenAPI validations failed" exit 1 fi