Fix compressed streaming responses at the kernel #368
Workflow file for this run
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: Gateway API Conformance | |
| # Guards that the WSO2 gateway keeps passing the Gateway API conformance suite. | |
| # Triggers: | |
| # - Pull requests that touch kubernetes/** (the operator, helm charts and the | |
| # conformance scripts) or gateway/gateway-controller/** (the xDS / route | |
| # translation conformance most directly exercises) — catches regressions before merge. | |
| # - Manual runs (workflow_dispatch). | |
| # - A weekly schedule (Saturday 00:00 UTC) so drift on main is caught even when no | |
| # triggering change lands. Saturday (not Friday) so the run happens after | |
| # Friday's changes have merged — otherwise a Friday-00:00 run would miss all of | |
| # Friday's work until the following week. | |
| # NOTE: under gateway/, only gateway-controller/** triggers this; the rest of gateway/** | |
| # (e.g. gateway-runtime, policies) does not — add more paths below if you want them to. | |
| on: | |
| workflow_dispatch: | |
| pull_request: | |
| branches: | |
| - main | |
| - gateway/1.2.0-agent-manager | |
| paths: | |
| - 'kubernetes/**' | |
| - 'gateway/gateway-controller/**' | |
| - '.github/workflows/k8s-gateway-api-conformance.yml' | |
| schedule: | |
| # Saturday at 00:00 UTC (cron day-of-week 6 = Saturday) — runs after Friday's | |
| # changes have landed, so each run covers the full week including Friday. | |
| - cron: '0 0 * * 6' | |
| concurrency: | |
| group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} | |
| cancel-in-progress: true | |
| permissions: | |
| contents: read | |
| env: | |
| # The conformance scripts derive image tags from gateway/VERSION and the operator | |
| # Makefile, and install-wso2-gateway.sh deploys those exact tags with | |
| # imagePullPolicy=IfNotPresent. So we build with the DEFAULT registry/version (no | |
| # overrides) and let load-images.sh line the tags up automatically. | |
| CONFORMANCE_DIR: kubernetes/conformance | |
| REPORT_OUT: ${{ github.workspace }}/conformance-report.yaml | |
| RUN_LOG: ${{ github.workspace }}/conformance-run.log | |
| jobs: | |
| conformance: | |
| runs-on: ubuntu-24.04 | |
| timeout-minutes: 90 | |
| outputs: | |
| # passed | failed (ran, some tests failed) | error (died before a report). | |
| # Consumed by the notify job below. Empty if the job died before the publish | |
| # step ran (e.g. an image build failure) — the notify job treats that as an error. | |
| status: ${{ steps.publish.outputs.status }} | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| - name: Set up Go | |
| uses: actions/setup-go@v5 | |
| with: | |
| go-version: '1.26.5' | |
| cache-dependency-path: '**/go.sum' | |
| - name: Set up QEMU | |
| uses: docker/setup-qemu-action@v3 | |
| with: | |
| platforms: linux/amd64,linux/arm64 | |
| - name: Set up Docker Buildx | |
| uses: docker/setup-buildx-action@v3 | |
| with: | |
| # docker driver builds straight into the local daemon so `kind load` / | |
| # load-images.sh can see the images. | |
| driver: docker | |
| - name: Set up Helm | |
| uses: azure/setup-helm@v4 | |
| - name: Install KinD CLI | |
| # setup-kind.sh requires the kind binary (kubectl, docker, jq, curl are already | |
| # present on ubuntu-24.04). Built via the Go toolchain that's already set up; | |
| # pin the version here if a reproducible kind CLI is desired. | |
| run: go install sigs.k8s.io/kind@latest | |
| # ---- Build the gateway images from source (default tags) ----------------- | |
| - name: Build gateway images (controller + runtime) | |
| run: make -C gateway build | |
| - name: Build operator image | |
| run: make -C kubernetes/gateway-operator docker-build | |
| # ---- Stand up the cluster and deploy via the conformance scripts --------- | |
| - name: Create KinD cluster with MetalLB | |
| run: bash "${CONFORMANCE_DIR}/kind/setup-kind.sh" | |
| - name: Load built images into the cluster | |
| run: bash "${CONFORMANCE_DIR}/load-images.sh" | |
| - name: Install cert-manager, operator and GatewayClass | |
| run: bash "${CONFORMANCE_DIR}/install-wso2-gateway.sh" | |
| # ---- Run the suite (never fails the step directly; the outcome is recorded | |
| # and enforced by the reporting step below) -------------------------- | |
| - name: Run Gateway API conformance suite | |
| id: run | |
| run: | | |
| set -o pipefail | |
| if bash "${CONFORMANCE_DIR}/run-conformance.sh" 2>&1 | tee "${RUN_LOG}"; then | |
| echo "outcome=passed" >> "$GITHUB_OUTPUT" | |
| else | |
| echo "outcome=failed" >> "$GITHUB_OUTPUT" | |
| fi | |
| # ---- Present the result --------------------------------------------------- | |
| # A report is written by the suite whenever it finishes running (pass OR | |
| # partial fail). If it is missing, the suite died during setup/build/cluster | |
| # bring-up and never reached report generation. | |
| - name: Publish conformance results | |
| id: publish | |
| run: | | |
| if [ -s "${REPORT_OUT}" ]; then | |
| { | |
| echo "## Gateway API Conformance Report" | |
| echo "" | |
| if [ "${{ steps.run.outputs.outcome }}" = "passed" ]; then | |
| echo "**Status: ✅ All conformance tests passed.**" | |
| else | |
| echo "**Status: ❌ Conformance suite completed with failures — full report below.**" | |
| fi | |
| echo "" | |
| echo '```yaml' | |
| cat "${REPORT_OUT}" | |
| echo '```' | |
| } >> "$GITHUB_STEP_SUMMARY" | |
| echo "==================== Gateway API Conformance Report ====================" | |
| cat "${REPORT_OUT}" | |
| echo "=======================================================================" | |
| if [ "${{ steps.run.outputs.outcome }}" != "passed" ]; then | |
| echo "status=failed" >> "$GITHUB_OUTPUT" | |
| echo "::error::Gateway API conformance suite reported failures. See the report above." | |
| exit 1 | |
| fi | |
| echo "status=passed" >> "$GITHUB_OUTPUT" | |
| echo "Gateway API conformance suite passed." | |
| else | |
| echo "status=error" >> "$GITHUB_OUTPUT" | |
| echo "::error::Conformance suite failed before a report could be generated (setup/build/cluster error)." | |
| { | |
| echo "## Gateway API Conformance — FAILED before report generation" | |
| echo "" | |
| echo "The suite did not produce a report. Tail of the run log:" | |
| echo '```' | |
| tail -n 300 "${RUN_LOG}" 2>/dev/null || echo "(no run log captured)" | |
| echo '```' | |
| } >> "$GITHUB_STEP_SUMMARY" | |
| echo "==================== Conformance run log (tail) ====================" | |
| tail -n 300 "${RUN_LOG}" 2>/dev/null || echo "(no run log captured)" | |
| echo "===================================================================" | |
| exit 1 | |
| fi | |
| - name: Upload conformance report and run log | |
| if: always() | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: gateway-api-conformance-report | |
| path: | | |
| ${{ env.REPORT_OUT }} | |
| ${{ env.RUN_LOG }} | |
| if-no-files-found: warn | |
| - name: Collect cluster diagnostics on failure | |
| if: failure() | |
| run: | | |
| echo "===== Pods (all namespaces) =====" | |
| kubectl get pods -A -o wide || true | |
| echo "===== Gateways =====" | |
| kubectl get gateways.gateway.networking.k8s.io -A || true | |
| echo "===== HTTPRoutes =====" | |
| kubectl get httproutes.gateway.networking.k8s.io -A || true | |
| echo "===== GatewayClass =====" | |
| kubectl get gatewayclass -A || true | |
| echo "===== Operator logs =====" | |
| kubectl logs -n gateway-system deploy/gateway-operator --tail=200 || true | |
| echo "===== Data-plane pods (conformance infra namespace) =====" | |
| kubectl get pods -n gateway-conformance-infra -o wide || true | |
| # Posts the conformance outcome to the configured Google Chat space — but ONLY for the | |
| # weekly scheduled run. Manual (workflow_dispatch) and pull_request runs are started by | |
| # someone who is already watching the Actions status, so a chat ping would be noise; | |
| # the scheduled run is the unattended monitor, so its result is the one the space needs. | |
| # always() lets it run even when the conformance job failed (a skipped dependency would | |
| # otherwise suppress the very failure we want to hear about). | |
| notify: | |
| name: Notify Google Chat | |
| needs: conformance | |
| if: always() && github.event_name == 'schedule' | |
| runs-on: ubuntu-24.04 | |
| steps: | |
| - name: Checkout conformance pin | |
| uses: actions/checkout@v4 | |
| with: | |
| sparse-checkout: kubernetes/conformance/runner/go.mod | |
| sparse-checkout-cone-mode: false | |
| # Compares the Gateway API version this suite is pinned to against the latest | |
| # upstream release, so a new release is noticed by the weekly run instead of by | |
| # someone remembering to check kubernetes-sigs/gateway-api by hand. | |
| - name: Check for a newer Gateway API release | |
| id: upstream | |
| env: | |
| # Raises the API rate limit from the shared-IP anonymous quota and needs no | |
| # scope beyond the workflow's top-level `contents: read`. | |
| GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| run: | | |
| set -uo pipefail | |
| GOMOD="kubernetes/conformance/runner/go.mod" | |
| # The `require sigs.k8s.io/gateway-api/conformance vX.Y.Z` line is the single | |
| # source of truth for what the suite actually runs (run-conformance.sh resolves | |
| # the suite from the module cache, not from a checkout of the upstream repo). | |
| PINNED=$(grep -oE 'sigs\.k8s\.io/gateway-api/conformance v[0-9]+\.[0-9]+\.[0-9]+' "${GOMOD}" \ | |
| | head -n1 | awk '{print $2}') | |
| if [ -z "${PINNED:-}" ]; then | |
| echo "::warning::Could not read the Gateway API conformance pin from ${GOMOD}; skipping the release check." | |
| echo "latest=" >> "$GITHUB_OUTPUT" | |
| exit 0 | |
| fi | |
| echo "pinned=${PINNED}" >> "$GITHUB_OUTPUT" | |
| # /releases/latest excludes drafts and pre-releases, so release candidates | |
| # (v1.6.0-rc1 and friends) never raise a false alarm. | |
| LATEST=$(curl --fail --silent --show-error --max-time 30 \ | |
| -H "Accept: application/vnd.github+json" \ | |
| -H "X-GitHub-Api-Version: 2022-11-28" \ | |
| -H "Authorization: Bearer ${GH_TOKEN}" \ | |
| https://api.github.com/repos/kubernetes-sigs/gateway-api/releases/latest \ | |
| | jq -r '.tag_name // empty') || LATEST="" | |
| # Validate before the value is ever interpolated into the chat payload | |
| if ! printf '%s' "${LATEST}" | grep -qE '^v[0-9]+\.[0-9]+\.[0-9]+$'; then | |
| echo "::warning::Could not resolve a usable latest Gateway API release tag (got '${LATEST}'); skipping the release check." | |
| echo "latest=" >> "$GITHUB_OUTPUT" | |
| exit 0 | |
| fi | |
| echo "Pinned Gateway API conformance version: ${PINNED}" | |
| echo "Latest upstream Gateway API release: ${LATEST}" | |
| # sort -V orders semver correctly (Ex: 1.10.0 after 1.9.0) | |
| NEWEST=$(printf '%s\n%s\n' "${PINNED#v}" "${LATEST#v}" | sort -V | tail -n1) | |
| if [ "${NEWEST}" = "${PINNED#v}" ]; then | |
| echo "Pin is up to date." | |
| echo "latest=" >> "$GITHUB_OUTPUT" | |
| exit 0 | |
| fi | |
| echo "::notice::Gateway API ${LATEST} is available; the conformance suite is pinned to ${PINNED}." | |
| echo "latest=${LATEST}" >> "$GITHUB_OUTPUT" | |
| - name: Send Google Chat notification | |
| env: | |
| WEBHOOK_URL: ${{ secrets.GOOGLE_CHATSPACE_WEBHOOK_URL }} | |
| # UPSTREAM_LATEST is empty unless a strictly newer Gateway API release exists; | |
| UPSTREAM_LATEST: ${{ steps.upstream.outputs.latest }} | |
| UPSTREAM_PINNED: ${{ steps.upstream.outputs.pinned }} | |
| # needs.<job>.result is success/failure/cancelled; the status output adds | |
| # detail (passed/failed/error). Passed via env to keep untrusted-looking | |
| # context out of the inline shell. | |
| RESULT: ${{ needs.conformance.result }} | |
| STATUS: ${{ needs.conformance.outputs.status }} | |
| REPO: ${{ github.repository }} | |
| REF_NAME: ${{ github.ref_name }} | |
| EVENT: ${{ github.event_name }} | |
| RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }} | |
| run: | | |
| set -euo pipefail | |
| if [ -z "${WEBHOOK_URL}" ]; then | |
| echo "GOOGLE_CHATSPACE_WEBHOOK_URL is not configured (e.g. a fork PR); skipping notification." | |
| exit 0 | |
| fi | |
| if [ "${RESULT}" = "success" ]; then | |
| HEADLINE="✅ *Gateway API Conformance Passed*" | |
| elif [ "${STATUS}" = "failed" ]; then | |
| # A report was produced but some conformance tests failed. | |
| HEADLINE="❌ *Gateway API Conformance Failed* — View Report: ${RUN_URL}" | |
| else | |
| # status=error, or empty because the job died before the report step | |
| # (image build / cluster bring-up / install failure). | |
| HEADLINE="🔥 *Gateway API Conformance Errored*" | |
| fi | |
| # Appended only when the release check found a newer upstream version. | |
| UPSTREAM_LINE="" | |
| if [ -n "${UPSTREAM_LATEST}" ]; then | |
| UPSTREAM_LINE="\n🔔 *(Alert):* Gateway-API ${UPSTREAM_LATEST} is now available — this suite is pinned to ${UPSTREAM_PINNED}." | |
| fi | |
| # Create the final message payload | |
| MESSAGE="${HEADLINE}\n*Repository:* ${REPO}\n*Ref:* ${REF_NAME}\n*Trigger:* ${EVENT}\n*Run:* ${RUN_URL}${UPSTREAM_LINE}" | |
| PAYLOAD="$(jq -cn --arg text "${MESSAGE}" '{text: $text}')" | |
| echo "${PAYLOAD}" | curl --fail --silent --show-error \ | |
| -X POST \ | |
| -H 'Content-Type: application/json' \ | |
| -d @- \ | |
| "${WEBHOOK_URL}" | |
| echo "Notification sent to Google Chat." |