From 5642449c2aa9e00d44051a11e5e78c35242ed74c Mon Sep 17 00:00:00 2001 From: Pranav Gawri Date: Tue, 26 Nov 2024 00:16:17 +0530 Subject: [PATCH 1/6] 1. Add rules file for GraphQL linting 2. Updated the CI pipeline, by grouping varied actions together. --- .../workflows/pull_request_merge_checks.yaml | 165 +++++++++++++----- .graphql-schema-linterrc | 8 + 2 files changed, 132 insertions(+), 41 deletions(-) create mode 100644 .graphql-schema-linterrc diff --git a/.github/workflows/pull_request_merge_checks.yaml b/.github/workflows/pull_request_merge_checks.yaml index a0ce0b1..24b09f8 100644 --- a/.github/workflows/pull_request_merge_checks.yaml +++ b/.github/workflows/pull_request_merge_checks.yaml @@ -1,27 +1,32 @@ -name: CI +name: API Contracts CI on: push: - branches: - - main + branches: [ main ] pull_request: - branches: - - main + branches: [ main ] + workflow_dispatch: jobs: - build: + detect-changes: runs-on: ubuntu-latest - name: Check API Contracts + outputs: + openapi_changed: ${{ steps.changed-files-specific.outputs.any_changed }} + graphql_changed: ${{ steps.changed-graphqls-files.outputs.any_changed }} + examples_changed: ${{ steps.changed-examples.outputs.any_changed }} + changed_graphql_files: ${{ steps.changed-graphqls-files.outputs.all_changed_files }} steps: - - uses: actions/checkout@v4 + - name: Checkout code + uses: actions/checkout@v4 with: - fetch-depth: 0 # OR "2" -> To retrieve the preceding commit. - - - uses: actions/setup-node@v2 + fetch-depth: 0 + + - name: Setup Node + uses: actions/setup-node@v2 with: node-version: '20' - - name: Get changed yaml files + - name: Detect OpenAPI Changes id: changed-files-specific uses: tj-actions/changed-files@v34 with: @@ -29,59 +34,137 @@ jobs: io/**/*.yaml io/**/*.yml io/**/*.json - files_ignore: kafka.yaml #skipping it as async is under private-beta + files_ignore: kafka.yaml - - name: Get changed GraphQLS files + - name: Detect GraphQL Changes id: changed-graphqls-files uses: tj-actions/changed-files@v34 with: files: | io/**/*.graphqls - - - name: Install Spectral Linter - if: steps.changed-files-specific.outputs.any_changed == 'true' - run: npm install -g @stoplight/spectral-cli - - name: Run Spectral linter on changed files - if: steps.changed-files-specific.outputs.any_changed == 'true' + - name: Detect Examples Changes + id: changed-examples + uses: tj-actions/changed-files@v34 + with: + files: | + **/*_examples/**/*.json + **/*_examples/**/*.yaml + + lint: + needs: detect-changes + if: needs.detect-changes.outputs.openapi_changed == 'true' || needs.detect-changes.outputs.graphql_changed == 'true' + runs-on: ubuntu-latest + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Setup Node + uses: actions/setup-node@v2 + with: + node-version: '20' + + - name: Install Spectral + if: needs.detect-changes.outputs.openapi_changed == 'true' + run: npm install -g @stoplight/spectral-cli + + - name: Run Spectral Linter for OpenAPI + if: needs.detect-changes.outputs.openapi_changed == 'true' run: | - echo "Running Spectral linter on: ${{ steps.changed-files-specific.outputs.all_changed_files }}" + echo "Running Spectral linter on changed OpenAPI files" spectral lint io/**/*.yaml + - name: Install GraphQL Schema Linter + if: needs.detect-changes.outputs.graphql_changed == 'true' + run: npm install -g graphql-schema-linter + + - name: Run GraphQL Schema Linter + if: needs.detect-changes.outputs.graphql_changed == 'true' + run: | + echo "Running GraphQL schema linter on changed files" + for file in ${{ needs.detect-changes.outputs.changed_graphql_files }}; do + echo "Linting $file..." + graphql-schema-linter "$file" + done + + setup-env: + runs-on: ubuntu-latest + outputs: + env_file: ${{ steps.create-env.outputs.env_file }} + steps: + - name: Create Environment File + id: create-env + run: | + echo "GITHUB_SHA=${{ github.sha }}" >> env.list + echo "GITHUB_REPOSITORY=${{ github.repository }}" >> env.list + echo "GITHUB_ACTOR=${{ github.actor }}" >> env.list + echo "GITHUB_WORKFLOW=${{ github.workflow }}" >> env.list + echo "GITHUB_HEAD_REF=${{ github.head_ref }}" >> env.list + if [ -z "${{ github.base_ref }}" ]; then + echo "GITHUB_BASE_REF=${{ github.ref }}" | sed 's/refs\/heads\///' >> env.list + else + echo "GITHUB_BASE_REF=${{ github.base_ref }}" >> env.list + fi + cat env.list + + examples-validation: + needs: [detect-changes, setup-env] + runs-on: ubuntu-latest + if: needs.detect-changes.outputs.openapi_changed == 'true' || needs.detect-changes.outputs.examples_changed == 'true' + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Validate OpenAPI Examples + run: | + docker run -v "$(pwd):/central-contract-repo:rw" \ + --env-file env.list \ + --entrypoint /bin/sh znsio/specmatic \ + -c "git config --global --add safe.directory /central-contract-repo && cd /central-contract-repo && java -jar /usr/src/app/specmatic.jar examples --validate io/**/*.yaml" + - name: Validate GraphQL examples run: | docker run -v "$(pwd):/central-contract-repo:rw" \ --entrypoint /bin/sh \ znsio/specmatic-graphql-trial \ -c "cd /central-contract-repo && java -jar /usr/src/app/specmatic-graphql.jar examples validate --spec-file io/specmatic/examples/store/graphql/products_bff.graphqls" - - - name: Create environment file - run: | - # echo "GITHUB_REF=${{ github.ref }}" >> env.list - echo "GITHUB_SHA=${{ github.sha }}" >> env.list - echo "GITHUB_REPOSITORY=${{ github.repository }}" >> env.list - echo "GITHUB_ACTOR=${{ github.actor }}" >> env.list - echo "GITHUB_WORKFLOW=${{ github.workflow }}" >> env.list - echo "GITHUB_HEAD_REF=${{ github.head_ref }}" >> env.list - if [ -z "${{ github.base_ref }}" ]; then - echo "GITHUB_BASE_REF=${{ github.ref }}" | sed 's/refs\/heads\///' >> env.list - else - echo "GITHUB_BASE_REF=${{ github.base_ref }}" >> env.list - fi - - - name: Run OpenAPI backward compatibility check on changed files - if: steps.changed-files-specific.outputs.any_changed == 'true' + + compatibility: + needs: [detect-changes, setup-env] + runs-on: ubuntu-latest + if: needs.detect-changes.outputs.openapi_changed == 'true' || needs.detect-changes.outputs.graphql_changed == 'true' + steps: + - name: Checkout code + uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: OpenAPI Compatibility Check + if: needs.detect-changes.outputs.openapi_changed == 'true' run: | docker run -v "$(pwd):/central-contract-repo:rw" \ --env-file env.list \ --entrypoint /bin/sh znsio/specmatic \ -c "git config --global --add safe.directory /central-contract-repo && cd /central-contract-repo && java -jar /usr/src/app/specmatic.jar backward-compatibility-check --base-branch origin/main" - - name: Run GraphQL backward compatibility check on changed files - if: steps.changed-graphqls-files.outputs.any_changed == 'true' + - name: GraphQL Compatibility Check + if: needs.detect-changes.outputs.graphql_changed == 'true' run: | docker run -v "$(pwd):/central-contract-repo:rw" \ --env-file env.list \ --entrypoint /bin/sh \ znsio/specmatic-graphql-trial \ - -c "git config --global --add safe.directory /central-contract-repo && cd /central-contract-repo && java -jar /usr/src/app/specmatic-graphql.jar backward-compatibility-check --base-branch origin/main" + -c "git config --global --add safe.directory /central-contract-repo && cd /central-contract-repo && java -jar /usr/bin/specmatic-graphql.jar backwardCompatibilityCheck" + + summary: + needs: [lint, examples-validation, compatibility] + if: always() + runs-on: ubuntu-latest + steps: + - name: Check Pipeline Status + run: | + if [[ "${{ needs.lint.result }}" == "failure" || \ + "${{ needs.examples-validation.result }}" == "failure" || \ + "${{ needs.compatibility.result }}" == "failure" ]]; then + exit 1 + fi \ No newline at end of file diff --git a/.graphql-schema-linterrc b/.graphql-schema-linterrc new file mode 100644 index 0000000..0b4806f --- /dev/null +++ b/.graphql-schema-linterrc @@ -0,0 +1,8 @@ +{ + "rules": [ + "defined-types-are-used", + "deprecations-have-a-reason", + "interface-fields-sorted-alphabetically", + "relay-connection-types-spec" + ] +} \ No newline at end of file From 5f830e1deec1d51befef1df976ccf48081027c20 Mon Sep 17 00:00:00 2001 From: Pranav Gawri Date: Tue, 26 Nov 2024 00:32:07 +0530 Subject: [PATCH 2/6] Making some changes to test the CI pipeline. --- io/specmatic/examples/store/grpc/order_bff.proto | 2 +- .../examples/store/grpc/order_bff_examples/createProduct.json | 2 +- io/specmatic/examples/store/openapi/product_search_bff_v4.yaml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/io/specmatic/examples/store/grpc/order_bff.proto b/io/specmatic/examples/store/grpc/order_bff.proto index 44bce6b..f4222e8 100644 --- a/io/specmatic/examples/store/grpc/order_bff.proto +++ b/io/specmatic/examples/store/grpc/order_bff.proto @@ -1,5 +1,5 @@ syntax = "proto3"; - + option java_multiple_files = true; option java_package = "com.store.order.bff.proto"; option go_package = "github.com/znsio/specmatic-order-bff-grpc-go/com/store/order/bff/proto"; diff --git a/io/specmatic/examples/store/grpc/order_bff_examples/createProduct.json b/io/specmatic/examples/store/grpc/order_bff_examples/createProduct.json index 24a6ef8..3afd6f1 100644 --- a/io/specmatic/examples/store/grpc/order_bff_examples/createProduct.json +++ b/io/specmatic/examples/store/grpc/order_bff_examples/createProduct.json @@ -3,7 +3,7 @@ "request": { "name": "Smartphone", "type": "GADGET", - "inventory": 100 + "inventory": 99 }, "response": { "id": 15 diff --git a/io/specmatic/examples/store/openapi/product_search_bff_v4.yaml b/io/specmatic/examples/store/openapi/product_search_bff_v4.yaml index 9e3b825..09982f6 100644 --- a/io/specmatic/examples/store/openapi/product_search_bff_v4.yaml +++ b/io/specmatic/examples/store/openapi/product_search_bff_v4.yaml @@ -177,7 +177,7 @@ paths: schema: $ref: '#/components/schemas/BadRequest' get: - summary: Retrieve order information + summary: Retrieve order information, this is work in progress. tags: - WIP parameters: From 6c0bcccd5e00b594c3965ebe07b46826cd94cf15 Mon Sep 17 00:00:00 2001 From: Pranav Gawri Date: Tue, 26 Nov 2024 00:49:33 +0530 Subject: [PATCH 3/6] Minor changes for testing --- .github/workflows/pull_request_merge_checks.yaml | 12 ++++++------ io/specmatic/examples/store/grpc/order_bff.proto | 2 +- .../store/grpc/order_bff_examples/createProduct.json | 2 +- .../store/openapi/product_search_bff_v4.yaml | 2 +- 4 files changed, 9 insertions(+), 9 deletions(-) diff --git a/.github/workflows/pull_request_merge_checks.yaml b/.github/workflows/pull_request_merge_checks.yaml index 24b09f8..6b8c05a 100644 --- a/.github/workflows/pull_request_merge_checks.yaml +++ b/.github/workflows/pull_request_merge_checks.yaml @@ -115,12 +115,12 @@ jobs: - name: Checkout code uses: actions/checkout@v4 - - name: Validate OpenAPI Examples - run: | - docker run -v "$(pwd):/central-contract-repo:rw" \ - --env-file env.list \ - --entrypoint /bin/sh znsio/specmatic \ - -c "git config --global --add safe.directory /central-contract-repo && cd /central-contract-repo && java -jar /usr/src/app/specmatic.jar examples --validate io/**/*.yaml" + # - name: Validate OpenAPI Examples + # run: | + # docker run -v "$(pwd):/central-contract-repo:rw" \ + # --env-file env.list \ + # --entrypoint /bin/sh znsio/specmatic \ + # -c "git config --global --add safe.directory /central-contract-repo && cd /central-contract-repo && java -jar /usr/src/app/specmatic.jar examples --validate io/**/*.yaml" - name: Validate GraphQL examples run: | diff --git a/io/specmatic/examples/store/grpc/order_bff.proto b/io/specmatic/examples/store/grpc/order_bff.proto index f4222e8..44bce6b 100644 --- a/io/specmatic/examples/store/grpc/order_bff.proto +++ b/io/specmatic/examples/store/grpc/order_bff.proto @@ -1,5 +1,5 @@ syntax = "proto3"; - + option java_multiple_files = true; option java_package = "com.store.order.bff.proto"; option go_package = "github.com/znsio/specmatic-order-bff-grpc-go/com/store/order/bff/proto"; diff --git a/io/specmatic/examples/store/grpc/order_bff_examples/createProduct.json b/io/specmatic/examples/store/grpc/order_bff_examples/createProduct.json index 3afd6f1..24a6ef8 100644 --- a/io/specmatic/examples/store/grpc/order_bff_examples/createProduct.json +++ b/io/specmatic/examples/store/grpc/order_bff_examples/createProduct.json @@ -3,7 +3,7 @@ "request": { "name": "Smartphone", "type": "GADGET", - "inventory": 99 + "inventory": 100 }, "response": { "id": 15 diff --git a/io/specmatic/examples/store/openapi/product_search_bff_v4.yaml b/io/specmatic/examples/store/openapi/product_search_bff_v4.yaml index 09982f6..9e3b825 100644 --- a/io/specmatic/examples/store/openapi/product_search_bff_v4.yaml +++ b/io/specmatic/examples/store/openapi/product_search_bff_v4.yaml @@ -177,7 +177,7 @@ paths: schema: $ref: '#/components/schemas/BadRequest' get: - summary: Retrieve order information, this is work in progress. + summary: Retrieve order information tags: - WIP parameters: From 307d60c5b7d1fe87bddd4556d5a60c6b39d918bf Mon Sep 17 00:00:00 2001 From: Pranav Gawri Date: Tue, 26 Nov 2024 00:52:20 +0530 Subject: [PATCH 4/6] Minor changes for testing --- io/specmatic/examples/store/grpc/order_bff.proto | 1 + .../examples/store/grpc/order_bff_examples/createProduct.json | 2 +- io/specmatic/examples/store/openapi/product_search_bff_v4.yaml | 2 +- 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/io/specmatic/examples/store/grpc/order_bff.proto b/io/specmatic/examples/store/grpc/order_bff.proto index 44bce6b..188a87e 100644 --- a/io/specmatic/examples/store/grpc/order_bff.proto +++ b/io/specmatic/examples/store/grpc/order_bff.proto @@ -20,6 +20,7 @@ enum ProductType { FOOD = 2; GADGET = 3; OTHER = 4; + TEST = 5; } message findAvailableProductsRequest { diff --git a/io/specmatic/examples/store/grpc/order_bff_examples/createProduct.json b/io/specmatic/examples/store/grpc/order_bff_examples/createProduct.json index 24a6ef8..a6f0d86 100644 --- a/io/specmatic/examples/store/grpc/order_bff_examples/createProduct.json +++ b/io/specmatic/examples/store/grpc/order_bff_examples/createProduct.json @@ -3,7 +3,7 @@ "request": { "name": "Smartphone", "type": "GADGET", - "inventory": 100 + "inventory": 98 }, "response": { "id": 15 diff --git a/io/specmatic/examples/store/openapi/product_search_bff_v4.yaml b/io/specmatic/examples/store/openapi/product_search_bff_v4.yaml index 9e3b825..07f1595 100644 --- a/io/specmatic/examples/store/openapi/product_search_bff_v4.yaml +++ b/io/specmatic/examples/store/openapi/product_search_bff_v4.yaml @@ -177,7 +177,7 @@ paths: schema: $ref: '#/components/schemas/BadRequest' get: - summary: Retrieve order information + summary: Retrieve order information, just adding some commends for testing tags: - WIP parameters: From 8282e5be61f03c207d1127dd0f09ab328db9752b Mon Sep 17 00:00:00 2001 From: Pranav Gawri Date: Tue, 26 Nov 2024 01:04:27 +0530 Subject: [PATCH 5/6] Updated the CI pipeline to fix compatibility error we were gettings --- .../workflows/pull_request_merge_checks.yaml | 41 ++++++++----------- 1 file changed, 18 insertions(+), 23 deletions(-) diff --git a/.github/workflows/pull_request_merge_checks.yaml b/.github/workflows/pull_request_merge_checks.yaml index 6b8c05a..df5b1ff 100644 --- a/.github/workflows/pull_request_merge_checks.yaml +++ b/.github/workflows/pull_request_merge_checks.yaml @@ -5,7 +5,6 @@ on: branches: [ main ] pull_request: branches: [ main ] - workflow_dispatch: jobs: detect-changes: @@ -87,28 +86,10 @@ jobs: graphql-schema-linter "$file" done - setup-env: - runs-on: ubuntu-latest - outputs: - env_file: ${{ steps.create-env.outputs.env_file }} - steps: - - name: Create Environment File - id: create-env - run: | - echo "GITHUB_SHA=${{ github.sha }}" >> env.list - echo "GITHUB_REPOSITORY=${{ github.repository }}" >> env.list - echo "GITHUB_ACTOR=${{ github.actor }}" >> env.list - echo "GITHUB_WORKFLOW=${{ github.workflow }}" >> env.list - echo "GITHUB_HEAD_REF=${{ github.head_ref }}" >> env.list - if [ -z "${{ github.base_ref }}" ]; then - echo "GITHUB_BASE_REF=${{ github.ref }}" | sed 's/refs\/heads\///' >> env.list - else - echo "GITHUB_BASE_REF=${{ github.base_ref }}" >> env.list - fi - cat env.list + examples-validation: - needs: [detect-changes, setup-env] + needs: [detect-changes] runs-on: ubuntu-latest if: needs.detect-changes.outputs.openapi_changed == 'true' || needs.detect-changes.outputs.examples_changed == 'true' steps: @@ -130,14 +111,28 @@ jobs: -c "cd /central-contract-repo && java -jar /usr/src/app/specmatic-graphql.jar examples validate --spec-file io/specmatic/examples/store/graphql/products_bff.graphqls" compatibility: - needs: [detect-changes, setup-env] + needs: [detect-changes] runs-on: ubuntu-latest if: needs.detect-changes.outputs.openapi_changed == 'true' || needs.detect-changes.outputs.graphql_changed == 'true' steps: - name: Checkout code uses: actions/checkout@v4 with: - fetch-depth: 0 + fetch-depth: 0 + + # Create env.list file before running Docker + - name: Create Environment File + run: | + echo "GITHUB_SHA=${{ github.sha }}" >> env.list + echo "GITHUB_REPOSITORY=${{ github.repository }}" >> env.list + echo "GITHUB_ACTOR=${{ github.actor }}" >> env.list + echo "GITHUB_WORKFLOW=${{ github.workflow }}" >> env.list + echo "GITHUB_HEAD_REF=${{ github.head_ref }}" >> env.list + if [ -z "${{ github.base_ref }}" ]; then + echo "GITHUB_BASE_REF=${{ github.ref }}" | sed 's/refs\/heads\///' >> env.list + else + echo "GITHUB_BASE_REF=${{ github.base_ref }}" >> env.list + fi - name: OpenAPI Compatibility Check if: needs.detect-changes.outputs.openapi_changed == 'true' From a26be90523d3e586d03ed065807f2a285ae2c08a Mon Sep 17 00:00:00 2001 From: Pranav Gawri Date: Tue, 26 Nov 2024 01:08:52 +0530 Subject: [PATCH 6/6] Undoing minor changes and running the checks again. --- io/specmatic/examples/store/grpc/order_bff.proto | 1 - .../examples/store/grpc/order_bff_examples/createProduct.json | 2 +- io/specmatic/examples/store/openapi/product_search_bff_v4.yaml | 2 +- 3 files changed, 2 insertions(+), 3 deletions(-) diff --git a/io/specmatic/examples/store/grpc/order_bff.proto b/io/specmatic/examples/store/grpc/order_bff.proto index 188a87e..44bce6b 100644 --- a/io/specmatic/examples/store/grpc/order_bff.proto +++ b/io/specmatic/examples/store/grpc/order_bff.proto @@ -20,7 +20,6 @@ enum ProductType { FOOD = 2; GADGET = 3; OTHER = 4; - TEST = 5; } message findAvailableProductsRequest { diff --git a/io/specmatic/examples/store/grpc/order_bff_examples/createProduct.json b/io/specmatic/examples/store/grpc/order_bff_examples/createProduct.json index a6f0d86..24a6ef8 100644 --- a/io/specmatic/examples/store/grpc/order_bff_examples/createProduct.json +++ b/io/specmatic/examples/store/grpc/order_bff_examples/createProduct.json @@ -3,7 +3,7 @@ "request": { "name": "Smartphone", "type": "GADGET", - "inventory": 98 + "inventory": 100 }, "response": { "id": 15 diff --git a/io/specmatic/examples/store/openapi/product_search_bff_v4.yaml b/io/specmatic/examples/store/openapi/product_search_bff_v4.yaml index 07f1595..9e3b825 100644 --- a/io/specmatic/examples/store/openapi/product_search_bff_v4.yaml +++ b/io/specmatic/examples/store/openapi/product_search_bff_v4.yaml @@ -177,7 +177,7 @@ paths: schema: $ref: '#/components/schemas/BadRequest' get: - summary: Retrieve order information, just adding some commends for testing + summary: Retrieve order information tags: - WIP parameters: